From 5772101b630d8a3835253b94f7dbf3e2bd1783a5 Mon Sep 17 00:00:00 2001 From: Jonson Petard <41122242+greenhat616@users.noreply.github.com> Date: Wed, 14 Feb 2024 18:00:44 +0800 Subject: [PATCH] fix: config migration issue --- backend/Cargo.lock | 8 ++--- backend/tauri/src/main.rs | 6 ++-- backend/tauri/src/utils/dialog.rs | 18 ++++++++-- backend/tauri/src/utils/help.rs | 15 ++++++++ backend/tauri/src/utils/init.rs | 58 +++++++++++++++++++++---------- 5 files changed, 78 insertions(+), 27 deletions(-) diff --git a/backend/Cargo.lock b/backend/Cargo.lock index c7a2cc7d72..528d3e6070 100644 --- a/backend/Cargo.lock +++ b/backend/Cargo.lock @@ -2060,9 +2060,9 @@ checksum = "95505c38b4572b2d910cecb0281560f54b440a19336cbbcb27bf6ce6adc6f5a8" [[package]] name = "hermit-abi" -version = "0.3.5" +version = "0.3.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d0c62115964e08cb8039170eb33c1d0e2388a256930279edca206fff675f82c3" +checksum = "bd5256b483761cd23699d0da46cc6fd2ee3be420bbe6d020ae4a091e70b7e9fd" [[package]] name = "hex" @@ -3665,9 +3665,9 @@ dependencies = [ [[package]] name = "pkg-config" -version = "0.3.29" +version = "0.3.30" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2900ede94e305130c13ddd391e0ab7cbaeb783945ae07a279c268cb05109c6cb" +checksum = "d231b230927b5e4ad203db57bbcbee2802f6bce620b1e4a9024a07d94e2907ec" [[package]] name = "plist" diff --git a/backend/tauri/src/main.rs b/backend/tauri/src/main.rs index 73fc904cc2..83faa103a7 100644 --- a/backend/tauri/src/main.rs +++ b/backend/tauri/src/main.rs @@ -25,9 +25,6 @@ fn main() -> std::io::Result<()> { crate::log_err!(init::init_config()); - let verge = { Config::verge().latest().language.clone().unwrap() }; - rust_i18n::set_locale(verge.as_str()); - // Panic Hook to show a panic dialog and save logs let default_panic = std::panic::take_hook(); std::panic::set_hook(Box::new(move |info| { @@ -36,6 +33,9 @@ fn main() -> std::io::Result<()> { default_panic(info); })); + let verge = { Config::verge().latest().language.clone().unwrap() }; + rust_i18n::set_locale(verge.as_str()); + #[allow(unused_mut)] let mut builder = tauri::Builder::default() .system_tray(SystemTray::new()) diff --git a/backend/tauri/src/utils/dialog.rs b/backend/tauri/src/utils/dialog.rs index a19ad37c90..d00cb3f507 100644 --- a/backend/tauri/src/utils/dialog.rs +++ b/backend/tauri/src/utils/dialog.rs @@ -1,6 +1,8 @@ use rust_i18n::t; -use std::sync::atomic::{AtomicBool, Ordering}; -use std::sync::{Arc, Barrier}; +use std::sync::{ + atomic::{AtomicBool, Ordering}, + Arc, Barrier, +}; use tauri::api::dialog::{MessageDialogBuilder, MessageDialogButtons, MessageDialogKind}; pub fn panic_dialog(msg: &str) { @@ -32,3 +34,15 @@ pub fn migrate_dialog() -> bool { barrier.wait(); migrate.load(Ordering::Relaxed) } + +pub fn error_dialog(msg: String) { + let barrier = Arc::new(Barrier::new(2)); + let barrier_ref = barrier.clone(); + MessageDialogBuilder::new("Error", msg) + .kind(MessageDialogKind::Error) + .buttons(MessageDialogButtons::Ok) + .show(move |_| { + barrier_ref.wait(); + }); + barrier.wait(); +} diff --git a/backend/tauri/src/utils/help.rs b/backend/tauri/src/utils/help.rs index ec5bc12f55..62b207ac8d 100644 --- a/backend/tauri/src/utils/help.rs +++ b/backend/tauri/src/utils/help.rs @@ -124,6 +124,21 @@ macro_rules! log_err { }; } +#[macro_export] +macro_rules! dialog_err { + ($result: expr) => { + if let Err(err) = $result { + crate::utils::dialog::error_dialog(format!("{:?}", err)); + } + }; + + ($result: expr, $err_str: expr) => { + if let Err(_) = $result { + crate::utils::dialog::error_dialog($err_str.into()); + } + }; +} + #[macro_export] macro_rules! trace_err { ($result: expr, $err_str: expr) => { diff --git a/backend/tauri/src/utils/init.rs b/backend/tauri/src/utils/init.rs index 5fec836827..4c12e3a177 100644 --- a/backend/tauri/src/utils/init.rs +++ b/backend/tauri/src/utils/init.rs @@ -1,7 +1,6 @@ -use crate::utils::dialog::migrate_dialog; use crate::{ config::*, - utils::{dirs, help}, + utils::{dialog::migrate_dialog, dirs, help}, }; use anyhow::Result; use chrono::Local; @@ -11,8 +10,8 @@ use log4rs::{ config::{Appender, Logger, Root}, encode::pattern::PatternEncoder, }; -use std::fs; -use std::path::PathBuf; +use runas::Command as RunasCommand; +use std::{fs, io::ErrorKind, path::PathBuf}; /// initialize this instance's log file fn init_log() -> Result<()> { @@ -79,27 +78,30 @@ pub fn init_config() -> Result<()> { #[cfg(target_os = "windows")] let _ = dirs::init_portable_flag(); - // Check if old config dir exist + // Check if old config dir exist and new config dir is not exist let mut old_app_dir: Option = None; - crate::log_err!(dirs::old_app_home_dir().map(|_old_app_dir| { - if _old_app_dir.exists() && migrate_dialog() { - old_app_dir = Some(_old_app_dir); - } + let mut app_dir: Option = None; + crate::dialog_err!(dirs::old_app_home_dir().map(|_old_app_dir| { + old_app_dir = Some(_old_app_dir); })); - let _ = init_log(); + crate::dialog_err!(dirs::app_home_dir().map(|_app_dir| { + app_dir = Some(_app_dir); + })); - crate::log_err!(dirs::app_home_dir().map(|app_dir| { - // Do migrate - if let Some(_old_app_dir) = old_app_dir { - let _ = fs::remove_dir_all(&app_dir); - let _ = fs::rename(_old_app_dir, &app_dir); + if let (Some(app_dir), Some(old_app_dir)) = (old_app_dir, app_dir) { + if !app_dir.exists() && old_app_dir.exists() && migrate_dialog() { + if let Err(e) = do_config_migration(&old_app_dir, &app_dir) { + super::dialog::error_dialog(format!("failed to do migration: {:?}", e)) + } } - if !app_dir.exists() { - let _ = fs::create_dir_all(&app_dir); + let _ = fs::create_dir_all(app_dir); } - })); + } + + // init log + let _ = init_log(); crate::log_err!(dirs::app_profiles_dir().map(|profiles_dir| { if !profiles_dir.exists() { @@ -254,3 +256,23 @@ pub fn init_service() -> Result<()> { Ok(()) } + +fn do_config_migration(old_app_dir: &PathBuf, app_dir: &PathBuf) -> anyhow::Result<()> { + if let Err(e) = fs::rename(old_app_dir, app_dir) { + match e.kind() { + #[cfg(windows)] + ErrorKind::PermissionDenied => { + // It seems that clash-verge-service is running, so kill it. + let status = RunasCommand::new("cmd") + .args(&["/C", "taskkill", "/IM", "clash-verge-service.exe", "/F"]) + .status()?; + if !status.success() { + anyhow::bail!("failed to kill clash-verge-service.exe") + } + fs::rename(old_app_dir, app_dir)?; + } + _ => return Err(e.into()), + }; + } + Ok(()) +}