diff --git a/Cargo.lock b/Cargo.lock index f36063209..865975717 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -7385,8 +7385,8 @@ dependencies = [ [[package]] name = "sysproxy" -version = "0.4.1" -source = "git+https://github.com/clash-verge-rev/sysproxy-rs#279a5cf1c4470d0b28af9a5c3fb7c2fcb503a906" +version = "0.4.2" +source = "git+https://github.com/clash-verge-rev/sysproxy-rs#51256d5921a01bbcf24fe5629296d2bfe493329d" dependencies = [ "interfaces", "iptools", diff --git a/Changelog.md b/Changelog.md index e6cf2f839..46dbeb3a3 100644 --- a/Changelog.md +++ b/Changelog.md @@ -67,6 +67,7 @@ - 改进旧版 Service 需要重新安装检测流程 - 优化 macOS, Linux 和 Windows 系统信号处理 - 链式代理仅显示 Selector 类型规则组 +- 优化 Windows 系统代理设置,不再依赖 `sysproxy.exe` 来设置代理 diff --git a/scripts/prebuild.mjs b/scripts/prebuild.mjs index 21f0da7cc..7325d571c 100644 --- a/scripts/prebuild.mjs +++ b/scripts/prebuild.mjs @@ -576,7 +576,7 @@ const resolveServicePermission = async () => { }; // ======================= -// Other resource resolvers (service, mmdb, geosite, geoip, enableLoopback, sysproxy) +// Other resource resolvers (service, mmdb, geosite, geoip, enableLoopback) // ======================= const SERVICE_URL = `https://github.com/clash-verge-rev/clash-verge-service-ipc/releases/download/${SIDECAR_HOST}`; const resolveService = () => { @@ -624,11 +624,6 @@ const resolveEnableLoopback = () => file: "enableLoopback.exe", downloadURL: `https://github.com/Kuingsmile/uwp-tool/releases/download/latest/enableLoopback.exe`, }); -const resolveWinSysproxy = () => - resolveResource({ - file: "sysproxy.exe", - downloadURL: `https://github.com/clash-verge-rev/sysproxy/releases/download/${arch}/sysproxy.exe`, - }); const resolveSetDnsScript = () => resolveResource({ @@ -676,12 +671,6 @@ const tasks = [ retry: 5, unixOnly: platform === "linux" || platform === "darwin", }, - { - name: "windows-sysproxy", - func: resolveWinSysproxy, - retry: 5, - winOnly: true, - }, { name: "set_dns_script", func: resolveSetDnsScript, diff --git a/src-tauri/src/core/sysopt.rs b/src-tauri/src/core/sysopt.rs index a4ef4b2bf..ca1a35200 100644 --- a/src-tauri/src/core/sysopt.rs +++ b/src-tauri/src/core/sysopt.rs @@ -23,7 +23,6 @@ use tauri_plugin_autostart::ManagerExt as _; pub struct Sysopt { update_sysproxy: AtomicBool, reset_sysproxy: AtomicBool, - #[cfg(not(target_os = "windows"))] inner_proxy: Arc>, guard: Arc>, } @@ -33,7 +32,6 @@ impl Default for Sysopt { Self { update_sysproxy: AtomicBool::new(false), reset_sysproxy: AtomicBool::new(false), - #[cfg(not(target_os = "windows"))] inner_proxy: Arc::new(RwLock::new((Sysproxy::default(), Autoproxy::default()))), guard: Arc::new(RwLock::new(GuardMonitor::new(GuardType::None, Duration::from_secs(30)))), } @@ -69,35 +67,6 @@ async fn get_bypass() -> String { } } -// Uses tokio Command with CREATE_NO_WINDOW flag to avoid DLL initialization issues during shutdown -#[cfg(target_os = "windows")] -async fn execute_sysproxy_command(args: Vec) -> Result<()> { - use crate::utils::dirs; - use anyhow::bail; - #[allow(unused_imports)] // Required for .creation_flags() method - use std::os::windows::process::CommandExt as _; - use tokio::process::Command; - - let binary_path = dirs::service_path()?; - let sysproxy_exe = binary_path.with_file_name("sysproxy.exe"); - - if !sysproxy_exe.exists() { - bail!("sysproxy.exe not found"); - } - - let output = Command::new(sysproxy_exe) - .args(args) - .creation_flags(0x08000000) // CREATE_NO_WINDOW - 隐藏窗口 - .output() - .await?; - - if !output.status.success() { - bail!("sysproxy exe run failed"); - } - - Ok(()) -} - singleton!(Sysopt, SYSOPT); impl Sysopt { @@ -112,12 +81,12 @@ impl Sysopt { pub async fn refresh_guard(&self) { logging!(info, Type::Core, "Refreshing system proxy guard..."); let verge = Config::verge().await.latest_arc(); - if !verge.enable_system_proxy.unwrap_or(false) { + if !verge.enable_system_proxy.unwrap_or_default() { logging!(info, Type::Core, "System proxy is disabled."); self.access_guard().write().stop(); return; } - if !verge.enable_proxy_guard.unwrap_or(false) { + if !verge.enable_proxy_guard.unwrap_or_default() { logging!(info, Type::Core, "System proxy guard is disabled."); return; } @@ -169,94 +138,62 @@ impl Sysopt { }; let pac_port = IVerge::get_singleton_port(); - let (sys_enable, pac_enable, proxy_host) = { + let (sys_enable, pac_enable, proxy_host, proxy_guard) = { ( - verge.enable_system_proxy.unwrap_or(false), - verge.proxy_auto_config.unwrap_or(false), + verge.enable_system_proxy.unwrap_or_default(), + verge.proxy_auto_config.unwrap_or_default(), verge.proxy_host.clone().unwrap_or_else(|| String::from("127.0.0.1")), + verge.enable_proxy_guard.unwrap_or_default(), ) }; - #[cfg(not(target_os = "windows"))] - { - // 先 await, 避免持有锁导致的 Send 问题 - let bypass = get_bypass().await; + // 先 await, 避免持有锁导致的 Send 问题 + let bypass = get_bypass().await; - let (sys, auto) = &mut *self.inner_proxy.write(); + let (sys, auto) = &mut *self.inner_proxy.write(); + sys.enable = false; + sys.host = proxy_host.clone().into(); + sys.port = port; + sys.bypass = bypass.into(); + + auto.enable = false; + auto.url = format!("http://{proxy_host}:{pac_port}/commands/pac"); + + self.access_guard().write().set_guard_type(GuardType::None); + + if !sys_enable && !pac_enable { + // disable proxy + sys.set_system_proxy()?; + auto.set_auto_proxy()?; + return Ok(()); + } + + if pac_enable { sys.enable = false; - sys.host = proxy_host.clone().into(); - sys.port = port; - sys.bypass = bypass.into(); - - auto.enable = false; - auto.url = format!("http://{proxy_host}:{pac_port}/commands/pac"); - - if !sys_enable { - sys.set_system_proxy()?; - auto.set_auto_proxy()?; - self.access_guard() - .write() - .set_guard_type(GuardType::Sysproxy(sys.clone())); - return Ok(()); - } - - if pac_enable { - sys.enable = false; - auto.enable = true; - sys.set_system_proxy()?; - auto.set_auto_proxy()?; + auto.enable = true; + sys.set_system_proxy()?; + auto.set_auto_proxy()?; + if proxy_guard { self.access_guard() .write() .set_guard_type(GuardType::Autoproxy(auto.clone())); - return Ok(()); } + return Ok(()); + } - if sys_enable { - auto.enable = false; - sys.enable = true; - auto.set_auto_proxy()?; - sys.set_system_proxy()?; + if sys_enable { + auto.enable = false; + sys.enable = true; + auto.set_auto_proxy()?; + sys.set_system_proxy()?; + if proxy_guard { self.access_guard() .write() .set_guard_type(GuardType::Sysproxy(sys.clone())); - return Ok(()); } + return Ok(()); } - #[cfg(target_os = "windows")] - { - if !sys_enable { - self.access_guard().write().set_guard_type(GuardType::None); - return self.reset_sysproxy().await; - } - - let (args, guard_type): (Vec, GuardType) = if pac_enable { - let address = format!("http://{proxy_host}:{pac_port}/commands/pac"); - ( - vec!["pac".into(), address.clone()], - GuardType::Autoproxy(Autoproxy { - enable: true, - url: address, - }), - ) - } else { - let address = format!("{proxy_host}:{port}"); - let bypass = get_bypass().await; - let bypass_for_guard = bypass.as_str().to_owned(); - ( - vec!["global".into(), address.clone(), bypass.into()], - GuardType::Sysproxy(Sysproxy { - enable: true, - host: proxy_host.clone().into(), - port, - bypass: bypass_for_guard, - }), - ) - }; - - execute_sysproxy_command(args).await?; - self.access_guard().write().set_guard_type(guard_type); - } Ok(()) } @@ -274,20 +211,15 @@ impl Sysopt { self.reset_sysproxy.store(false, Ordering::SeqCst); } - //直接关闭所有代理 - #[cfg(not(target_os = "windows"))] - { - let (sys, auto) = &mut *self.inner_proxy.write(); - sys.enable = false; - sys.set_system_proxy()?; - auto.enable = false; - auto.set_auto_proxy()?; - } + // close proxy guard + self.access_guard().write().set_guard_type(GuardType::None); - #[cfg(target_os = "windows")] - { - execute_sysproxy_command(vec!["set".into(), "1".into()]).await?; - } + // 直接关闭所有代理 + let (sys, auto) = &mut *self.inner_proxy.write(); + sys.enable = false; + sys.set_system_proxy()?; + auto.enable = false; + auto.set_auto_proxy()?; Ok(()) } diff --git a/src-tauri/src/feat/window.rs b/src-tauri/src/feat/window.rs index 1f41abf71..d2d4ba1f4 100644 --- a/src-tauri/src/feat/window.rs +++ b/src-tauri/src/feat/window.rs @@ -45,93 +45,25 @@ pub async fn clean_async() -> bool { // 重置系统代理 let proxy_task = tokio::task::spawn(async { - #[cfg(target_os = "windows")] - { - use sysproxy::{Autoproxy, Sysproxy}; - use winapi::um::winuser::{GetSystemMetrics, SM_SHUTTINGDOWN}; - - // 检查系统代理是否开启 - let sys_proxy_enabled = Config::verge().await.data_arc().enable_system_proxy.unwrap_or(false); - - if !sys_proxy_enabled { - logging!(info, Type::Window, "系统代理未启用,跳过重置"); - return true; - } - - // 检查是否正在关机 - let is_shutting_down = unsafe { GetSystemMetrics(SM_SHUTTINGDOWN) != 0 }; - - if is_shutting_down { - // sysproxy-rs 操作注册表(避免.exe的dll错误) - logging!(info, Type::Window, "检测到正在关机,syspro-rs操作注册表关闭系统代理"); - - match Sysproxy::get_system_proxy() { - Ok(mut sysproxy) => { - sysproxy.enable = false; - if let Err(e) = sysproxy.set_system_proxy() { - logging!(warn, Type::Window, "Warning: 关机时关闭系统代理失败: {e}"); - } else { - logging!(info, Type::Window, "系统代理已关闭(通过注册表)"); - } - } - Err(e) => { - logging!(warn, Type::Window, "Warning: 关机时获取代理设置失败: {e}"); - } - } - - // 关闭自动代理配置 - if let Ok(mut autoproxy) = Autoproxy::get_auto_proxy() { - autoproxy.enable = false; - let _ = autoproxy.set_auto_proxy(); - } - - return true; - } - - // 正常退出:使用 sysproxy.exe 重置代理 - logging!(info, Type::Window, "sysproxy.exe重置系统代理"); - - match timeout(Duration::from_secs(2), sysopt::Sysopt::global().reset_sysproxy()).await { - Ok(Ok(_)) => { - logging!(info, Type::Window, "系统代理已重置"); - true - } - Ok(Err(e)) => { - logging!(warn, Type::Window, "Warning: 重置系统代理失败: {e}"); - true - } - Err(_) => { - logging!(warn, Type::Window, "Warning: 重置系统代理超时,继续退出流程"); - true - } - } + let sys_proxy_enabled = Config::verge().await.data_arc().enable_system_proxy.unwrap_or(false); + if !sys_proxy_enabled { + logging!(info, Type::Window, "系统代理未启用,跳过重置"); + return true; } - // 非 Windows 平台:正常重置代理 - #[cfg(not(target_os = "windows"))] - { - let sys_proxy_enabled = Config::verge().await.data_arc().enable_system_proxy.unwrap_or(false); - - if !sys_proxy_enabled { - logging!(info, Type::Window, "系统代理未启用,跳过重置"); - return true; + logging!(info, Type::Window, "开始重置系统代理..."); + match timeout(Duration::from_millis(1500), sysopt::Sysopt::global().reset_sysproxy()).await { + Ok(Ok(_)) => { + logging!(info, Type::Window, "系统代理已重置"); + true } - - logging!(info, Type::Window, "开始重置系统代理..."); - - match timeout(Duration::from_millis(1500), sysopt::Sysopt::global().reset_sysproxy()).await { - Ok(Ok(_)) => { - logging!(info, Type::Window, "系统代理已重置"); - true - } - Ok(Err(e)) => { - logging!(warn, Type::Window, "Warning: 重置系统代理失败: {e}"); - true - } - Err(_) => { - logging!(warn, Type::Window, "Warning: 重置系统代理超时,继续退出"); - true - } + Ok(Err(e)) => { + logging!(warn, Type::Window, "Warning: 重置系统代理失败: {e}"); + false + } + Err(_) => { + logging!(warn, Type::Window, "Warning: 重置系统代理超时,继续退出"); + false } } }); @@ -183,7 +115,7 @@ pub async fn clean_async() -> bool { Type::Window, "Warning: 停止core超时(可能系统正在关机),继续退出" ); - true + false } } });