From 804e02004d8cf5b41a3e1f9b9cef2ca219725067 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=88=98=E8=88=AA=E5=AE=87?= <3364451258@qq.com> Date: Tue, 26 May 2026 22:04:16 +0800 Subject: [PATCH] =?UTF-8?q?fix:=20backup=5Fregistry=20=E6=94=B9=E4=B8=BA?= =?UTF-8?q?=E5=86=85=E9=83=A8=E8=AF=BB=E5=8F=96=E6=B3=A8=E5=86=8C=E8=A1=A8?= =?UTF-8?q?=E5=BD=93=E5=89=8D=E5=80=BC=EF=BC=8C=E4=B8=8D=E5=86=8D=E4=BE=9D?= =?UTF-8?q?=E8=B5=96=E5=89=8D=E7=AB=AF=E4=BC=A0=E5=85=A5=E6=95=B0=E6=8D=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-Authored-By: Claude Opus 4.7 --- src-tauri/src/commands/backup.rs | 35 ++++++++++++++++++++---------- src-tauri/src/commands/registry.rs | 8 +++---- src/store/app-store.ts | 4 ++-- 3 files changed, 30 insertions(+), 17 deletions(-) diff --git a/src-tauri/src/commands/backup.rs b/src-tauri/src/commands/backup.rs index b9a4868..f566543 100644 --- a/src-tauri/src/commands/backup.rs +++ b/src-tauri/src/commands/backup.rs @@ -1,5 +1,4 @@ use chrono::Local; -use std::fs; use std::path::PathBuf; fn backup_base_dir() -> PathBuf { @@ -17,27 +16,41 @@ pub fn get_appdata_dir() -> String { } /// 备份当前注册表中的系统 PATH 和用户 PATH -/// 返回备份文件的路径 +/// 在保存前调用,备份的是注册表中的当前值(保存前的状态) #[tauri::command] -pub fn backup_registry(custom_dir: Option, sys_paths: Vec, user_paths: Vec) -> Result { - // 确定备份目录 +pub fn backup_registry(custom_dir: Option) -> Result { + use crate::commands::registry; + use winreg::enums::*; + let backup_dir = match custom_dir { - Some(ref dir) if !dir.is_empty() => PathBuf::from(dir), + Some(ref dir) if !dir.is_empty() => std::path::PathBuf::from(dir), _ => backup_base_dir(), }; - // 创建目录 - fs::create_dir_all(&backup_dir) + std::fs::create_dir_all(&backup_dir) .map_err(|e| format!("无法创建备份目录: {}", e))?; - // 生成带时间戳的文件名 + // 读取当前注册表中的值(保存前的旧值) + let sys_paths = registry::load_paths( + HKEY_LOCAL_MACHINE, + "SYSTEM\\CurrentControlSet\\Control\\Session Manager\\Environment", + "系统", + )?; + let user_paths = registry::load_paths( + HKEY_CURRENT_USER, + "Environment", + "用户", + )?; + let timestamp = Local::now().format("%Y%m%d_%H%M%S_%3f"); let filename = format!("path_backup_{}.txt", timestamp); let filepath = backup_dir.join(&filename); - // 写入备份内容 let mut content = String::new(); - content.push_str(&format!("PathEditor Backup - {}\n", Local::now().format("%Y-%m-%d %H:%M:%S"))); + content.push_str(&format!( + "PathEditor Backup - {}\n", + Local::now().format("%Y-%m-%d %H:%M:%S") + )); content.push_str("\n[System PATH]\n"); for path in &sys_paths { content.push_str(&format!("{}\n", path)); @@ -47,7 +60,7 @@ pub fn backup_registry(custom_dir: Option, sys_paths: Vec, user_ content.push_str(&format!("{}\n", path)); } - fs::write(&filepath, &content) + std::fs::write(&filepath, &content) .map_err(|e| format!("无法写入备份文件: {}", e))?; let result = filepath.to_string_lossy().to_string(); diff --git a/src-tauri/src/commands/registry.rs b/src-tauri/src/commands/registry.rs index 42fe128..29bffa8 100644 --- a/src-tauri/src/commands/registry.rs +++ b/src-tauri/src/commands/registry.rs @@ -5,7 +5,7 @@ const SYS_REG_PATH: &str = "SYSTEM\\CurrentControlSet\\Control\\Session Manager\ const USER_REG_PATH: &str = "Environment"; const PATH_VALUE: &str = "Path"; -fn load_paths(root: winreg::HKEY, sub_path: &str, label: &str) -> Result, String> { +pub(crate) fn load_paths(root: winreg::HKEY, sub_path: &str, label: &str) -> Result, String> { let key = RegKey::predef(root); let env_key = key .open_subkey_with_flags(sub_path, KEY_READ) @@ -18,7 +18,7 @@ fn load_paths(root: winreg::HKEY, sub_path: &str, label: &str) -> Result Result<(), String> { +pub(crate) fn save_paths(root: winreg::HKEY, sub_path: &str, label: &str, paths: &[String]) -> Result<(), String> { let value = join_path(paths); // Windows 注册表 REG_EXPAND_SZ 上限 32767 字符 @@ -63,14 +63,14 @@ pub fn save_user_paths(paths: Vec) -> Result<(), String> { save_paths(HKEY_CURRENT_USER, USER_REG_PATH, "用户", &paths) } -fn split_path(raw: &str) -> Vec { +pub(crate) fn split_path(raw: &str) -> Vec { raw.split(';') .map(|s| s.trim().to_string()) .filter(|s| !s.is_empty()) .collect() } -fn join_path(paths: &[String]) -> String { +pub(crate) fn join_path(paths: &[String]) -> String { paths .iter() .map(|p| p.trim()) diff --git a/src/store/app-store.ts b/src/store/app-store.ts index 7fbd053..8dbfda1 100644 --- a/src/store/app-store.ts +++ b/src/store/app-store.ts @@ -259,8 +259,8 @@ export const useAppStore = create((set, get) => ({ if (!window.confirm('PATH 长度超过建议值,是否继续保存?')) { set({ isSaving: false }); return; } } - // 备份(失败时通知用户) - invoke('backup_registry', { customDir: null, sysPaths, userPaths }) + // 备份当前注册表(保存前备份旧值,失败仅警告不中断) + invoke('backup_registry', { customDir: null }) .catch(() => set({ statusMessage: i18n.t('status.warning_backup') })); const [sysResult, userResult] = await Promise.allSettled([