From bcc5ec897aa6748755ffb5321e53efb1a396b11e Mon Sep 17 00:00:00 2001 From: GyDi Date: Fri, 18 Nov 2022 20:15:34 +0800 Subject: [PATCH] fix: windows issue --- src-tauri/src/core/core.rs | 15 ++++++++------- src-tauri/src/core/win_service.rs | 14 +++++++++----- src-tauri/src/feat.rs | 14 ++++++++++---- src-tauri/src/utils/dirs.rs | 29 ++++++++++++++++++----------- 4 files changed, 45 insertions(+), 27 deletions(-) diff --git a/src-tauri/src/core/core.rs b/src-tauri/src/core/core.rs index b45ddf3..342c202 100644 --- a/src-tauri/src/core/core.rs +++ b/src-tauri/src/core/core.rs @@ -74,6 +74,10 @@ impl CoreManager { pub async fn run_core(&self) -> Result<()> { let config_path = Config::generate_file(ConfigType::Run)?; + if let Some(child) = self.sidecar.lock().take() { + let _ = child.kill(); + } + #[cfg(target_os = "windows")] { use super::win_service; @@ -90,7 +94,7 @@ impl CoreManager { // 服务模式启动失败就直接运行sidecar match { win_service::check_service().await?; - win_service::run_core_by_service().await + win_service::run_core_by_service(&config_path).await } { Ok(_) => return Ok(()), Err(err) => { @@ -103,12 +107,6 @@ impl CoreManager { } } - let mut sidecar = self.sidecar.lock(); - - if let Some(child) = sidecar.take() { - let _ = child.kill(); - } - let app_dir = dirs::app_home_dir()?; let app_dir = dirs::path_to_str(&app_dir)?; @@ -137,6 +135,7 @@ impl CoreManager { >::Ok(()) }); + let mut sidecar = self.sidecar.lock(); *sidecar = Some(cmd_child); tauri::async_runtime::spawn(async move { @@ -193,6 +192,8 @@ impl CoreManager { bail!("invalid clash core name \"{clash_core}\""); } + log::debug!(target: "app", "change core to `{clash_core}`"); + Config::verge().draft().clash_core = Some(clash_core); // 清掉旧日志 diff --git a/src-tauri/src/core/win_service.rs b/src-tauri/src/core/win_service.rs index b4ef1a1..f3f8850 100644 --- a/src-tauri/src/core/win_service.rs +++ b/src-tauri/src/core/win_service.rs @@ -8,6 +8,7 @@ use runas::Command as RunasCommand; use serde::{Deserialize, Serialize}; use std::collections::HashMap; use std::os::windows::process::CommandExt; +use std::path::PathBuf; use std::time::Duration; use std::{env::current_exe, process::Command as StdCommand}; use tokio::time::sleep; @@ -32,7 +33,7 @@ pub struct JsonResponse { /// Install the Clash Verge Service /// 该函数应该在协程或者线程中执行,避免UAC弹窗阻塞主线程 pub async fn install_service() -> Result<()> { - let binary_path = dirs::service_path(); + let binary_path = dirs::service_path()?; let install_path = binary_path.with_file_name("install-service.exe"); if !install_path.exists() { @@ -62,7 +63,7 @@ pub async fn install_service() -> Result<()> { /// Uninstall the Clash Verge Service /// 该函数应该在协程或者线程中执行,避免UAC弹窗阻塞主线程 pub async fn uninstall_service() -> Result<()> { - let binary_path = dirs::service_path(); + let binary_path = dirs::service_path()?; let uninstall_path = binary_path.with_file_name("uninstall-service.exe"); if !uninstall_path.exists() { @@ -106,7 +107,7 @@ pub async fn check_service() -> Result { } /// start the clash by service -pub(super) async fn run_core_by_service() -> Result<()> { +pub(super) async fn run_core_by_service(config_file: &PathBuf) -> Result<()> { let status = check_service().await?; if status.code == 0 { @@ -121,16 +122,19 @@ pub(super) async fn run_core_by_service() -> Result<()> { let bin_path = current_exe()?.with_file_name(clash_bin); let bin_path = dirs::path_to_str(&bin_path)?; - let config_dir = dirs::app_home_dir(); + let config_dir = dirs::app_home_dir()?; let config_dir = dirs::path_to_str(&config_dir)?; - let log_path = dirs::service_log_file(); + let log_path = dirs::service_log_file()?; let log_path = dirs::path_to_str(&log_path)?; + let config_file = dirs::path_to_str(config_file)?; + let mut map = HashMap::new(); map.insert("core_type", clash_core.as_str()); map.insert("bin_path", bin_path); map.insert("config_dir", config_dir); + map.insert("config_file", config_file); map.insert("log_file", log_path); let url = format!("{SERVICE_URL}/start_clash"); diff --git a/src-tauri/src/feat.rs b/src-tauri/src/feat.rs index 1648453..00d2ae2 100644 --- a/src-tauri/src/feat.rs +++ b/src-tauri/src/feat.rs @@ -42,9 +42,7 @@ pub fn change_clash_mode(mode: String) { log_err!(handle::Handle::update_systray_part()); } } - Err(err) => { - log::error!(target: "app", "{err}"); - } + Err(err) => log::error!(target: "app", "{err}"), } }); } @@ -211,9 +209,17 @@ pub async fn patch_verge(patch: IVerge) -> Result<()> { match { #[cfg(target_os = "windows")] { - todo!() + let service_mode = patch.enable_service_mode; + + if service_mode.is_some() { + Config::generate()?; + CoreManager::global().run_core().await?; + } else if tun_mode.is_some() { + update_core_config().await?; + } } + #[cfg(not(target_os = "windows"))] if tun_mode.is_some() { update_core_config().await?; } diff --git a/src-tauri/src/utils/dirs.rs b/src-tauri/src/utils/dirs.rs index 553408a..9e99365 100644 --- a/src-tauri/src/utils/dirs.rs +++ b/src-tauri/src/utils/dirs.rs @@ -116,30 +116,37 @@ pub fn app_res_dir() -> Result { } pub fn clash_pid_path() -> Result { - unsafe { Ok(RESOURCE_DIR.clone().unwrap().join("clash.pid")) } -} - -#[cfg(windows)] -pub fn service_path() -> PathBuf { unsafe { - let res_dir = RESOURCE_DIR.clone().unwrap(); - res_dir.join("clash-verge-service.exe") + Ok(RESOURCE_DIR + .clone() + .ok_or(anyhow::anyhow!("failed to get the resource dir"))? + .join("clash.pid")) } } #[cfg(windows)] -pub fn service_log_file() -> PathBuf { +pub fn service_path() -> Result { + unsafe { + let res_dir = RESOURCE_DIR + .clone() + .ok_or(anyhow::anyhow!("failed to get the resource dir"))?; + Ok(res_dir.join("clash-verge-service.exe")) + } +} + +#[cfg(windows)] +pub fn service_log_file() -> Result { use chrono::Local; - let log_dir = app_logs_dir().join("service"); + let log_dir = app_logs_dir()?.join("service"); let local_time = Local::now().format("%Y-%m-%d-%H%M").to_string(); let log_file = format!("{}.log", local_time); let log_file = log_dir.join(log_file); - std::fs::create_dir_all(&log_dir).unwrap(); + let _ = std::fs::create_dir_all(&log_dir); - log_file + Ok(log_file) } pub fn path_to_str(path: &PathBuf) -> Result<&str> {