diff --git a/src-tauri/Cargo.lock b/src-tauri/Cargo.lock index f763b7302..80e7c3a14 100644 --- a/src-tauri/Cargo.lock +++ b/src-tauri/Cargo.lock @@ -7151,13 +7151,14 @@ dependencies = [ [[package]] name = "sysproxy" -version = "0.3.1" -source = "git+https://github.com/clash-verge-rev/sysproxy-rs#ea6e5b5bcef32025e1df914d663eea8558afacb2" +version = "0.4.0" +source = "git+https://github.com/clash-verge-rev/sysproxy-rs#0f844dd2639b0ac74da4548b1325335844947420" dependencies = [ "interfaces", "iptools", "log", "thiserror 2.0.17", + "tokio", "url", "windows 0.62.2", "winreg 0.55.0", diff --git a/src-tauri/Cargo.toml b/src-tauri/Cargo.toml index d66363973..e3bcc8516 100755 --- a/src-tauri/Cargo.toml +++ b/src-tauri/Cargo.toml @@ -42,7 +42,9 @@ tokio = { version = "1.48.0", features = [ serde = { version = "1.0.228", features = ["derive"] } reqwest = { version = "0.12.24", features = ["json", "cookies"] } regex = "1.12.2" -sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs" } +sysproxy = { git = "https://github.com/clash-verge-rev/sysproxy-rs", features = [ + "guard", +] } tauri = { version = "2.9.3", features = [ "protocol-asset", "devtools", diff --git a/src-tauri/src/cmd/network.rs b/src-tauri/src/cmd/network.rs index d6a9b5e2c..ba780962a 100644 --- a/src-tauri/src/cmd/network.rs +++ b/src-tauri/src/cmd/network.rs @@ -1,7 +1,5 @@ use super::CmdResult; use crate::cmd::StringifyErr as _; -use crate::core::{EventDrivenProxyManager, async_proxy_query::AsyncProxyQuery}; -use crate::process::AsyncHandler; use crate::{logging, utils::logging::Type}; use gethostname::gethostname; use network_interface::NetworkInterface; @@ -12,23 +10,23 @@ use serde_yaml_ng::Mapping; pub async fn get_sys_proxy() -> CmdResult { logging!(debug, Type::Network, "异步获取系统代理配置"); - let current = AsyncProxyQuery::get_system_proxy().await; + let sys_proxy = sysproxy::Sysproxy::get_system_proxy().stringify_err()?; let mut map = Mapping::new(); - map.insert("enable".into(), current.enable.into()); + map.insert("enable".into(), sys_proxy.enable.into()); map.insert( "server".into(), - format!("{}:{}", current.host, current.port).into(), + format!("{}:{}", sys_proxy.host, sys_proxy.port).into(), ); - map.insert("bypass".into(), current.bypass.into()); + map.insert("bypass".into(), sys_proxy.bypass.into()); logging!( debug, Type::Network, "返回系统代理配置: enable={}, {}:{}", - current.enable, - current.host, - current.port + sys_proxy.enable, + sys_proxy.host, + sys_proxy.port ); Ok(map) } @@ -36,26 +34,18 @@ pub async fn get_sys_proxy() -> CmdResult { /// 获取自动代理配置 #[tauri::command] pub async fn get_auto_proxy() -> CmdResult { - logging!(debug, Type::Network, "开始获取自动代理配置(事件驱动)"); - - let proxy_manager = EventDrivenProxyManager::global(); - - let current = proxy_manager.get_auto_proxy_cached().await; - // 异步请求更新,立即返回缓存数据 - AsyncHandler::spawn(move || async move { - let _ = proxy_manager.get_auto_proxy_async().await; - }); + let auto_proxy = sysproxy::Autoproxy::get_auto_proxy().stringify_err()?; let mut map = Mapping::new(); - map.insert("enable".into(), current.enable.into()); - map.insert("url".into(), current.url.clone().into()); + map.insert("enable".into(), auto_proxy.enable.into()); + map.insert("url".into(), auto_proxy.url.clone().into()); logging!( debug, Type::Network, "返回自动代理配置(缓存): enable={}, url={}", - current.enable, - current.url + auto_proxy.enable, + auto_proxy.url ); Ok(map) } diff --git a/src-tauri/src/constants.rs b/src-tauri/src/constants.rs index 37f0750ad..93ef8e872 100644 --- a/src-tauri/src/constants.rs +++ b/src-tauri/src/constants.rs @@ -1,7 +1,6 @@ use std::time::Duration; pub mod network { - pub const DEFAULT_PROXY_HOST: &str = "127.0.0.1"; pub const DEFAULT_EXTERNAL_CONTROLLER: &str = "127.0.0.1:9097"; pub mod ports { @@ -20,18 +19,6 @@ pub mod network { } } -pub mod bypass { - #[cfg(target_os = "windows")] - pub const DEFAULT: &str = "localhost;127.*;192.168.*;10.*;172.16.*;172.17.*;172.18.*;172.19.*;172.20.*;172.21.*;172.22.*;172.23.*;172.24.*;172.25.*;172.26.*;172.27.*;172.28.*;172.29.*;172.30.*;172.31.*;"; - - #[cfg(target_os = "linux")] - pub const DEFAULT: &str = - "localhost,127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,172.29.0.0/16,::1"; - - #[cfg(target_os = "macos")] - pub const DEFAULT: &str = "127.0.0.1,192.168.0.0/16,10.0.0.0/8,172.16.0.0/12,172.29.0.0/16,localhost,*.local,*.crashlytics.com,"; -} - pub mod timing { use super::Duration; diff --git a/src-tauri/src/core/async_proxy_query.rs b/src-tauri/src/core/async_proxy_query.rs deleted file mode 100644 index 3e99eb44e..000000000 --- a/src-tauri/src/core/async_proxy_query.rs +++ /dev/null @@ -1,561 +0,0 @@ -#[cfg(target_os = "windows")] -use crate::process::AsyncHandler; -use crate::{logging, utils::logging::Type}; -use anyhow::Result; -use serde::{Deserialize, Serialize}; -use tokio::time::{Duration, timeout}; - -#[cfg(target_os = "linux")] -use anyhow::anyhow; -#[cfg(not(target_os = "windows"))] -use tokio::process::Command; - -#[derive(Debug, Clone, Serialize, Deserialize, Default)] -pub struct AsyncAutoproxy { - pub enable: bool, - pub url: String, -} - -#[derive(Debug, Clone, Serialize, Deserialize)] -pub struct AsyncSysproxy { - pub enable: bool, - pub host: String, - pub port: u16, - pub bypass: String, -} - -impl Default for AsyncSysproxy { - fn default() -> Self { - Self { - enable: false, - host: "127.0.0.1".into(), - port: 7897, - bypass: String::new(), - } - } -} - -pub struct AsyncProxyQuery; - -impl AsyncProxyQuery { - /// 异步获取自动代理配置(PAC) - pub async fn get_auto_proxy() -> AsyncAutoproxy { - match timeout(Duration::from_secs(3), Self::get_auto_proxy_impl()).await { - Ok(Ok(proxy)) => { - logging!( - debug, - Type::Network, - "异步获取自动代理成功: enable={}, url={}", - proxy.enable, - proxy.url - ); - proxy - } - Ok(Err(e)) => { - logging!(warn, Type::Network, "Warning: 异步获取自动代理失败: {e}"); - AsyncAutoproxy::default() - } - Err(_) => { - logging!(warn, Type::Network, "Warning: 异步获取自动代理超时"); - AsyncAutoproxy::default() - } - } - } - - /// 异步获取系统代理配置 - pub async fn get_system_proxy() -> AsyncSysproxy { - match timeout(Duration::from_secs(3), Self::get_system_proxy_impl()).await { - Ok(Ok(proxy)) => { - logging!( - debug, - Type::Network, - "异步获取系统代理成功: enable={}, {}:{}", - proxy.enable, - proxy.host, - proxy.port - ); - proxy - } - Ok(Err(e)) => { - logging!(warn, Type::Network, "Warning: 异步获取系统代理失败: {e}"); - AsyncSysproxy::default() - } - Err(_) => { - logging!(warn, Type::Network, "Warning: 异步获取系统代理超时"); - AsyncSysproxy::default() - } - } - } - - #[cfg(target_os = "windows")] - async fn get_auto_proxy_impl() -> Result { - // Windows: 从注册表读取PAC配置 - let proxy = AsyncHandler::spawn_blocking(Self::get_pac_config_from_registry).await?; - Ok(proxy) - } - - #[cfg(target_os = "windows")] - fn get_pac_config_from_registry() -> AsyncAutoproxy { - use std::ptr; - use winapi::shared::minwindef::{DWORD, HKEY}; - use winapi::um::winnt::{KEY_READ, REG_DWORD, REG_SZ}; - use winapi::um::winreg::{HKEY_CURRENT_USER, RegCloseKey, RegOpenKeyExW, RegQueryValueExW}; - - unsafe { - let key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\0" - .encode_utf16() - .collect::>(); - - let mut hkey: HKEY = ptr::null_mut(); - let result = - RegOpenKeyExW(HKEY_CURRENT_USER, key_path.as_ptr(), 0, KEY_READ, &mut hkey); - - if result != 0 { - logging!(debug, Type::Network, "无法打开注册表项"); - return AsyncAutoproxy::default(); - } - - // 1. 检查自动配置是否启用 (AutoConfigURL 存在且不为空即表示启用) - let auto_config_url_name = "AutoConfigURL\0".encode_utf16().collect::>(); - let mut url_buffer = vec![0u16; 1024]; - let mut url_buffer_size: DWORD = (url_buffer.len() * 2) as DWORD; - let mut url_value_type: DWORD = 0; - - let url_query_result = RegQueryValueExW( - hkey, - auto_config_url_name.as_ptr(), - ptr::null_mut(), - &mut url_value_type, - url_buffer.as_mut_ptr() as *mut u8, - &mut url_buffer_size, - ); - - let mut pac_url = String::new(); - if url_query_result == 0 && url_value_type == REG_SZ && url_buffer_size > 0 { - let end_pos = url_buffer - .iter() - .position(|&x| x == 0) - .unwrap_or(url_buffer.len()); - pac_url = String::from_utf16_lossy(&url_buffer[..end_pos]); - logging!(debug, Type::Network, "从注册表读取到PAC URL: {pac_url}"); - } - - // 2. 检查自动检测设置是否启用 - let auto_detect_name = "AutoDetect\0".encode_utf16().collect::>(); - let mut auto_detect: DWORD = 0; - let mut detect_buffer_size: DWORD = 4; - let mut detect_value_type: DWORD = 0; - - let detect_query_result = RegQueryValueExW( - hkey, - auto_detect_name.as_ptr(), - ptr::null_mut(), - &mut detect_value_type, - &mut auto_detect as *mut DWORD as *mut u8, - &mut detect_buffer_size, - ); - - RegCloseKey(hkey); - - // PAC 启用的条件:AutoConfigURL 不为空,或 AutoDetect 被启用 - let pac_enabled = !pac_url.is_empty() - || (detect_query_result == 0 && detect_value_type == REG_DWORD && auto_detect != 0); - - if pac_enabled { - logging!( - debug, - Type::Network, - "PAC配置启用: URL={pac_url}, AutoDetect={auto_detect}" - ); - - if pac_url.is_empty() && auto_detect != 0 { - pac_url = "auto-detect".into(); - } - - AsyncAutoproxy { - enable: true, - url: pac_url, - } - } else { - logging!(debug, Type::Network, "PAC配置未启用"); - AsyncAutoproxy::default() - } - } - } - - #[cfg(target_os = "macos")] - async fn get_auto_proxy_impl() -> Result { - // macOS: 使用 scutil --proxy 命令 - let output = Command::new("scutil").args(["--proxy"]).output().await?; - - if !output.status.success() { - return Ok(AsyncAutoproxy::default()); - } - - let stdout = String::from_utf8_lossy(&output.stdout); - crate::logging!( - debug, - crate::utils::logging::Type::Network, - "scutil output: {stdout}" - ); - - let mut pac_enabled = false; - let mut pac_url = String::new(); - - // 解析 scutil 输出 - for line in stdout.lines() { - let line = line.trim(); - if line.contains("ProxyAutoConfigEnable") && line.contains("1") { - pac_enabled = true; - } else if line.contains("ProxyAutoConfigURLString") { - // 正确解析包含冒号的URL - // 格式: "ProxyAutoConfigURLString : http://127.0.0.1:11233/commands/pac" - if let Some(colon_pos) = line.find(" : ") { - pac_url = line[colon_pos + 3..].trim().into(); - } - } - } - - crate::logging!( - debug, - crate::utils::logging::Type::Network, - "解析结果: pac_enabled={pac_enabled}, pac_url={pac_url}" - ); - - Ok(AsyncAutoproxy { - enable: pac_enabled && !pac_url.is_empty(), - url: pac_url, - }) - } - - #[cfg(target_os = "linux")] - async fn get_auto_proxy_impl() -> Result { - // Linux: 检查环境变量和GNOME设置 - - // 首先检查环境变量 - if let Ok(auto_proxy) = std::env::var("auto_proxy") - && !auto_proxy.is_empty() - { - return Ok(AsyncAutoproxy { - enable: true, - url: auto_proxy, - }); - } - - // 尝试使用 gsettings 获取 GNOME 代理设置 - let output = Command::new("gsettings") - .args(["get", "org.gnome.system.proxy", "mode"]) - .output() - .await; - - if let Ok(output) = output - && output.status.success() - { - let mode: String = String::from_utf8_lossy(&output.stdout).trim().into(); - if mode.contains("auto") { - // 获取 PAC URL - let pac_output = Command::new("gsettings") - .args(["get", "org.gnome.system.proxy", "autoconfig-url"]) - .output() - .await; - - if let Ok(pac_output) = pac_output - && pac_output.status.success() - { - let pac_url: String = String::from_utf8_lossy(&pac_output.stdout) - .trim() - .trim_matches('\'') - .trim_matches('"') - .into(); - - if !pac_url.is_empty() { - return Ok(AsyncAutoproxy { - enable: true, - url: pac_url, - }); - } - } - } - } - - Ok(AsyncAutoproxy::default()) - } - - #[cfg(target_os = "windows")] - async fn get_system_proxy_impl() -> Result { - // Windows: 使用注册表直接读取代理设置 - let sys = AsyncHandler::spawn_blocking(Self::get_system_proxy_from_registry).await?; - Ok(sys) - } - - #[cfg(target_os = "windows")] - fn get_system_proxy_from_registry() -> AsyncSysproxy { - use std::ptr; - use winapi::shared::minwindef::{DWORD, HKEY}; - use winapi::um::winnt::{KEY_READ, REG_DWORD, REG_SZ}; - use winapi::um::winreg::{HKEY_CURRENT_USER, RegCloseKey, RegOpenKeyExW, RegQueryValueExW}; - - unsafe { - let key_path = "Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\0" - .encode_utf16() - .collect::>(); - - let mut hkey: HKEY = ptr::null_mut(); - let result = - RegOpenKeyExW(HKEY_CURRENT_USER, key_path.as_ptr(), 0, KEY_READ, &mut hkey); - - if result != 0 { - return AsyncSysproxy::default(); - } - - // 检查代理是否启用 - let proxy_enable_name = "ProxyEnable\0".encode_utf16().collect::>(); - let mut proxy_enable: DWORD = 0; - let mut buffer_size: DWORD = 4; - let mut value_type: DWORD = 0; - - let enable_result = RegQueryValueExW( - hkey, - proxy_enable_name.as_ptr(), - ptr::null_mut(), - &mut value_type, - &mut proxy_enable as *mut DWORD as *mut u8, - &mut buffer_size, - ); - - if enable_result != 0 || value_type != REG_DWORD || proxy_enable == 0 { - RegCloseKey(hkey); - return AsyncSysproxy::default(); - } - - // 读取代理服务器设置 - let proxy_server_name = "ProxyServer\0".encode_utf16().collect::>(); - let mut buffer = vec![0u16; 1024]; - let mut buffer_size: DWORD = (buffer.len() * 2) as DWORD; - let mut value_type: DWORD = 0; - - let server_result = RegQueryValueExW( - hkey, - proxy_server_name.as_ptr(), - ptr::null_mut(), - &mut value_type, - buffer.as_mut_ptr() as *mut u8, - &mut buffer_size, - ); - - let proxy_server = if server_result == 0 && value_type == REG_SZ && buffer_size > 0 { - let end_pos = buffer.iter().position(|&x| x == 0).unwrap_or(buffer.len()); - String::from_utf16_lossy(&buffer[..end_pos]) - } else { - String::new() - }; - - // 读取代理绕过列表 - let proxy_override_name = "ProxyOverride\0".encode_utf16().collect::>(); - let mut bypass_buffer = vec![0u16; 1024]; - let mut bypass_buffer_size: DWORD = (bypass_buffer.len() * 2) as DWORD; - let mut bypass_value_type: DWORD = 0; - - let override_result = RegQueryValueExW( - hkey, - proxy_override_name.as_ptr(), - ptr::null_mut(), - &mut bypass_value_type, - bypass_buffer.as_mut_ptr() as *mut u8, - &mut bypass_buffer_size, - ); - - let bypass_list = - if override_result == 0 && bypass_value_type == REG_SZ && bypass_buffer_size > 0 { - let end_pos = bypass_buffer - .iter() - .position(|&x| x == 0) - .unwrap_or(bypass_buffer.len()); - String::from_utf16_lossy(&bypass_buffer[..end_pos]) - } else { - String::new() - }; - - RegCloseKey(hkey); - - if !proxy_server.is_empty() { - // 解析服务器地址和端口 - let (host, port) = if let Some(colon_pos) = proxy_server.rfind(':') { - let host = proxy_server[..colon_pos].into(); - let port = proxy_server[colon_pos + 1..].parse::().unwrap_or(8080); - (host, port) - } else { - (proxy_server, 8080) - }; - - logging!( - debug, - Type::Network, - "从注册表读取到代理设置: {host}:{port}, bypass: {bypass_list}" - ); - - AsyncSysproxy { - enable: true, - host, - port, - bypass: bypass_list, - } - } else { - AsyncSysproxy::default() - } - } - } - - #[cfg(target_os = "macos")] - async fn get_system_proxy_impl() -> Result { - let output = Command::new("scutil").args(["--proxy"]).output().await?; - - if !output.status.success() { - return Ok(AsyncSysproxy::default()); - } - - let stdout = String::from_utf8_lossy(&output.stdout); - logging!(debug, Type::Network, "scutil proxy output: {stdout}"); - - let mut http_enabled = false; - let mut http_host = String::new(); - let mut http_port = 8080u16; - let mut exceptions: Vec = Vec::new(); - - for line in stdout.lines() { - let line = line.trim(); - if line.contains("HTTPEnable") && line.contains("1") { - http_enabled = true; - } else if line.contains("HTTPProxy") && !line.contains("Port") { - if let Some(host_part) = line.split(':').nth(1) { - http_host = host_part.trim().into(); - } - } else if line.contains("HTTPPort") { - if let Some(port_part) = line.split(':').nth(1) - && let Ok(port) = port_part.trim().parse::() - { - http_port = port; - } - } else if line.contains("ExceptionsList") { - // 解析异常列表 - if let Some(list_part) = line.split(':').nth(1) { - let list = list_part.trim(); - if !list.is_empty() { - exceptions.push(list.into()); - } - } - } - } - - Ok(AsyncSysproxy { - enable: http_enabled && !http_host.is_empty(), - host: http_host, - port: http_port, - bypass: exceptions.join(","), - }) - } - - #[cfg(target_os = "linux")] - async fn get_system_proxy_impl() -> Result { - // Linux: 检查环境变量和桌面环境设置 - - // 首先检查环境变量 - if let Ok(http_proxy) = std::env::var("http_proxy") - && let Ok(proxy_info) = Self::parse_proxy_url(&http_proxy) - { - return Ok(proxy_info); - } - - if let Ok(https_proxy) = std::env::var("https_proxy") - && let Ok(proxy_info) = Self::parse_proxy_url(&https_proxy) - { - return Ok(proxy_info); - } - - // 尝试使用 gsettings 获取 GNOME 代理设置 - let mode_output = Command::new("gsettings") - .args(["get", "org.gnome.system.proxy", "mode"]) - .output() - .await; - - if let Ok(mode_output) = mode_output - && mode_output.status.success() - { - let mode: String = String::from_utf8_lossy(&mode_output.stdout).trim().into(); - if mode.contains("manual") { - // 获取HTTP代理设置 - let host_result = Command::new("gsettings") - .args(["get", "org.gnome.system.proxy.http", "host"]) - .output() - .await; - - let port_result = Command::new("gsettings") - .args(["get", "org.gnome.system.proxy.http", "port"]) - .output() - .await; - - if let (Ok(host_output), Ok(port_output)) = (host_result, port_result) - && host_output.status.success() - && port_output.status.success() - { - let host: String = String::from_utf8_lossy(&host_output.stdout) - .trim() - .trim_matches('\'') - .trim_matches('"') - .into(); - - let port = String::from_utf8_lossy(&port_output.stdout) - .trim() - .parse::() - .unwrap_or(8080); - - if !host.is_empty() { - return Ok(AsyncSysproxy { - enable: true, - host, - port, - bypass: String::new(), - }); - } - } - } - } - - Ok(AsyncSysproxy::default()) - } - - #[cfg(target_os = "linux")] - fn parse_proxy_url(proxy_url: &str) -> Result { - // 解析形如 "http://proxy.example.com:8080" 的URL - let url = proxy_url.trim(); - - // 移除协议前缀 - let url = if let Some(stripped) = url.strip_prefix("http://") { - stripped - } else if let Some(stripped) = url.strip_prefix("https://") { - stripped - } else { - url - }; - - // 解析主机和端口 - let (host, port) = if let Some(colon_pos) = url.rfind(':') { - let host: String = url[..colon_pos].into(); - let port = url[colon_pos + 1..].parse::().unwrap_or(8080); - (host, port) - } else { - (url.into(), 8080) - }; - - if host.is_empty() { - return Err(anyhow!("无效的代理URL")); - } - - Ok(AsyncSysproxy { - enable: true, - host, - port, - bypass: std::env::var("no_proxy").unwrap_or_default(), - }) - } -} diff --git a/src-tauri/src/core/event_driven_proxy.rs b/src-tauri/src/core/event_driven_proxy.rs deleted file mode 100644 index e03e9eeca..000000000 --- a/src-tauri/src/core/event_driven_proxy.rs +++ /dev/null @@ -1,548 +0,0 @@ -use std::sync::Arc; -use tokio::sync::RwLock; -use tokio::sync::{mpsc, oneshot}; -use tokio::time::{Duration, sleep, timeout}; -use tokio_stream::{StreamExt as _, wrappers::UnboundedReceiverStream}; - -use crate::config::{Config, IVerge}; -use crate::core::{async_proxy_query::AsyncProxyQuery, handle}; -use crate::process::AsyncHandler; -use crate::{logging, utils::logging::Type}; -use once_cell::sync::Lazy; -use smartstring::alias::String; -use sysproxy::{Autoproxy, Sysproxy}; - -#[derive(Debug, Clone)] -pub enum ProxyEvent { - /// 配置变更事件 - ConfigChanged, - /// 应用启动事件 - AppStarted, - /// 应用关闭事件 - AppStopping, -} - -#[derive(Debug, Clone)] -pub struct ProxyState { - pub sys_enabled: bool, - pub pac_enabled: bool, - pub auto_proxy: Autoproxy, - pub sys_proxy: Sysproxy, - pub last_updated: std::time::Instant, - pub is_healthy: bool, -} - -impl Default for ProxyState { - fn default() -> Self { - Self { - sys_enabled: false, - pac_enabled: false, - auto_proxy: Autoproxy { - enable: false, - url: "".into(), - }, - sys_proxy: Sysproxy { - enable: false, - host: "127.0.0.1".into(), - port: 7897, - bypass: "".into(), - }, - last_updated: std::time::Instant::now(), - is_healthy: true, - } - } -} - -pub struct EventDrivenProxyManager { - state: Arc>, - event_sender: mpsc::UnboundedSender, - query_sender: mpsc::UnboundedSender, -} - -#[derive(Debug)] -pub struct QueryRequest { - response_tx: oneshot::Sender, -} - -// 配置结构体移到外部 -struct ProxyConfig { - sys_enabled: bool, - pac_enabled: bool, - guard_enabled: bool, - guard_duration: u64, -} - -static PROXY_MANAGER: Lazy = Lazy::new(EventDrivenProxyManager::new); - -impl EventDrivenProxyManager { - pub fn global() -> &'static Self { - &PROXY_MANAGER - } - - fn new() -> Self { - let state = Arc::new(RwLock::new(ProxyState::default())); - let (event_tx, event_rx) = mpsc::unbounded_channel(); - let (query_tx, query_rx) = mpsc::unbounded_channel(); - - let state_clone = Arc::clone(&state); - AsyncHandler::spawn(move || Self::start_event_loop(state_clone, event_rx, query_rx)); - - Self { - state, - event_sender: event_tx, - query_sender: query_tx, - } - } - - /// 获取自动代理配置(缓存) - pub async fn get_auto_proxy_cached(&self) -> Autoproxy { - self.state.read().await.auto_proxy.clone() - } - - /// 异步获取最新的自动代理配置 - pub async fn get_auto_proxy_async(&self) -> Autoproxy { - let (tx, rx) = oneshot::channel(); - let query = QueryRequest { response_tx: tx }; - - if self.query_sender.send(query).is_err() { - logging!(error, Type::Network, "发送查询请求失败,返回缓存数据"); - return self.get_auto_proxy_cached().await; - } - - match timeout(Duration::from_secs(5), rx).await { - Ok(Ok(result)) => result, - _ => { - logging!(warn, Type::Network, "Warning: 查询超时,返回缓存数据"); - self.get_auto_proxy_cached().await - } - } - } - - /// 通知配置变更 - pub fn notify_config_changed(&self) { - self.send_event(ProxyEvent::ConfigChanged); - } - - /// 通知应用启动 - pub fn notify_app_started(&self) { - self.send_event(ProxyEvent::AppStarted); - } - - /// 通知应用即将关闭 - pub fn notify_app_stopping(&self) { - self.send_event(ProxyEvent::AppStopping); - } - - fn send_event(&self, event: ProxyEvent) { - if let Err(e) = self.event_sender.send(event) { - logging!(error, Type::Network, "发送代理事件失败: {e}"); - } - } - - pub async fn start_event_loop( - state: Arc>, - event_rx: mpsc::UnboundedReceiver, - query_rx: mpsc::UnboundedReceiver, - ) { - logging!(info, Type::Network, "事件驱动代理管理器启动"); - - // 将 mpsc 接收器包装成 Stream,避免每次循环创建 future - let mut event_stream = UnboundedReceiverStream::new(event_rx); - let mut query_stream = UnboundedReceiverStream::new(query_rx); - - // 初始化定时器,用于周期性检查代理设置 - let config = Self::get_proxy_config().await; - let mut guard_interval = tokio::time::interval(Duration::from_secs(config.guard_duration)); - // 防止首次立即触发 - guard_interval.tick().await; - - loop { - tokio::select! { - Some(event) = event_stream.next() => { - logging!(debug, Type::Network, "处理代理事件: {event:?}"); - let event_clone = event.clone(); // 保存一份副本用于后续检查 - Self::handle_event(&state, event).await; - - // 检查是否是配置变更事件,如果是,则可能需要更新定时器 - if matches!(event_clone, ProxyEvent::ConfigChanged | ProxyEvent::AppStarted) { - let new_config = Self::get_proxy_config().await; - // 重新设置定时器间隔 - guard_interval = tokio::time::interval(Duration::from_secs(new_config.guard_duration)); - // 防止首次立即触发 - guard_interval.tick().await; - } - } - Some(query) = query_stream.next() => { - let result = Self::handle_query(&state).await; - let _ = query.response_tx.send(result); - } - _ = guard_interval.tick() => { - // 定时检查代理设置 - let config = Self::get_proxy_config().await; - if config.guard_enabled && config.sys_enabled { - logging!(debug, Type::Network, "定时检查代理设置"); - Self::check_and_restore_proxy(&state).await; - } - } - else => { - // 两个通道都关闭时退出 - logging!(info, Type::Network, "事件或查询通道关闭,代理管理器停止"); - break; - } - } - } - } - - async fn handle_event(state: &Arc>, event: ProxyEvent) { - match event { - ProxyEvent::ConfigChanged => { - Self::update_proxy_config(state).await; - } - ProxyEvent::AppStarted => { - Self::initialize_proxy_state(state).await; - } - ProxyEvent::AppStopping => { - logging!(info, Type::Network, "清理代理状态"); - Self::update_state_timestamp(state, |s| { - s.sys_enabled = false; - s.pac_enabled = false; - s.is_healthy = false; - }) - .await; - } - } - } - - async fn handle_query(state: &Arc>) -> Autoproxy { - let auto_proxy = Self::get_auto_proxy_with_timeout().await; - - Self::update_state_timestamp(state, |s| { - s.auto_proxy = auto_proxy.clone(); - }) - .await; - - auto_proxy - } - - async fn initialize_proxy_state(state: &Arc>) { - logging!(info, Type::Network, "初始化代理状态"); - - let config = Self::get_proxy_config().await; - let auto_proxy = Self::get_auto_proxy_with_timeout().await; - let sys_proxy = Self::get_sys_proxy_with_timeout().await; - - Self::update_state_timestamp(state, |s| { - s.sys_enabled = config.sys_enabled; - s.pac_enabled = config.pac_enabled; - s.auto_proxy = auto_proxy; - s.sys_proxy = sys_proxy; - s.is_healthy = true; - }) - .await; - - logging!( - info, - Type::Network, - "代理状态初始化完成: sys={}, pac={}", - config.sys_enabled, - config.pac_enabled - ); - } - - async fn update_proxy_config(state: &Arc>) { - logging!(debug, Type::Network, "更新代理配置"); - - let config = Self::get_proxy_config().await; - - Self::update_state_timestamp(state, |s| { - s.sys_enabled = config.sys_enabled; - s.pac_enabled = config.pac_enabled; - }) - .await; - - if config.guard_enabled && config.sys_enabled { - Self::check_and_restore_proxy(state).await; - } - } - - async fn check_and_restore_proxy(state: &Arc>) { - if handle::Handle::global().is_exiting() { - logging!(debug, Type::Network, "应用正在退出,跳过系统代理守卫检查"); - return; - } - let (sys_enabled, pac_enabled) = { - let s = state.read().await; - (s.sys_enabled, s.pac_enabled) - }; - - if !sys_enabled { - return; - } - - logging!(debug, Type::Network, "检查代理状态"); - - if pac_enabled { - Self::check_and_restore_pac_proxy(state).await; - } else { - Self::check_and_restore_sys_proxy(state).await; - } - } - - async fn check_and_restore_pac_proxy(state: &Arc>) { - if handle::Handle::global().is_exiting() { - logging!(debug, Type::Network, "应用正在退出,跳过PAC代理恢复检查"); - return; - } - - let current = Self::get_auto_proxy_with_timeout().await; - let expected = Self::get_expected_pac_config().await; - - Self::update_state_timestamp(state, |s| { - s.auto_proxy = current.clone(); - }) - .await; - - if !current.enable || current.url != expected.url { - logging!(info, Type::Network, "PAC代理设置异常,正在恢复..."); - if let Err(e) = Self::restore_pac_proxy(&expected.url).await { - logging!(error, Type::Network, "恢复PAC代理失败: {}", e); - } - - sleep(Duration::from_millis(500)).await; - let restored = Self::get_auto_proxy_with_timeout().await; - - Self::update_state_timestamp(state, |s| { - s.is_healthy = restored.enable && restored.url == expected.url; - s.auto_proxy = restored; - }) - .await; - } - } - - async fn check_and_restore_sys_proxy(state: &Arc>) { - if handle::Handle::global().is_exiting() { - logging!(debug, Type::Network, "应用正在退出,跳过系统代理恢复检查"); - return; - } - - let current = Self::get_sys_proxy_with_timeout().await; - let expected = Self::get_expected_sys_proxy().await; - - Self::update_state_timestamp(state, |s| { - s.sys_proxy = current.clone(); - }) - .await; - - if !current.enable || current.host != expected.host || current.port != expected.port { - logging!(info, Type::Network, "系统代理设置异常,正在恢复..."); - if let Err(e) = Self::restore_sys_proxy(&expected).await { - logging!(error, Type::Network, "恢复系统代理失败: {}", e); - } - - sleep(Duration::from_millis(500)).await; - let restored = Self::get_sys_proxy_with_timeout().await; - - Self::update_state_timestamp(state, |s| { - s.is_healthy = restored.enable - && restored.host == expected.host - && restored.port == expected.port; - s.sys_proxy = restored; - }) - .await; - } - } - - async fn get_auto_proxy_with_timeout() -> Autoproxy { - let async_proxy = AsyncProxyQuery::get_auto_proxy().await; - - // 转换为兼容的结构 - Autoproxy { - enable: async_proxy.enable, - url: async_proxy.url, - } - } - - async fn get_sys_proxy_with_timeout() -> Sysproxy { - let async_proxy = AsyncProxyQuery::get_system_proxy().await; - - // 转换为兼容的结构 - Sysproxy { - enable: async_proxy.enable, - host: async_proxy.host, - port: async_proxy.port, - bypass: async_proxy.bypass, - } - } - - // 统一的状态更新方法 - async fn update_state_timestamp(state: &Arc>, update_fn: F) - where - F: FnOnce(&mut ProxyState), - { - let mut state_guard = state.write().await; - update_fn(&mut state_guard); - state_guard.last_updated = std::time::Instant::now(); - } - - async fn get_proxy_config() -> ProxyConfig { - let (sys_enabled, pac_enabled, guard_enabled, guard_duration) = { - let verge_config = Config::verge().await; - let verge = verge_config.latest_arc(); - ( - verge.enable_system_proxy.unwrap_or(false), - verge.proxy_auto_config.unwrap_or(false), - verge.enable_proxy_guard.unwrap_or(false), - verge.proxy_guard_duration.unwrap_or(30), // 默认30秒 - ) - }; - ProxyConfig { - sys_enabled, - pac_enabled, - guard_enabled, - guard_duration, - } - } - - async fn get_expected_pac_config() -> Autoproxy { - let proxy_host = { - let verge_config = Config::verge().await; - let verge = verge_config.latest_arc(); - verge - .proxy_host - .clone() - .unwrap_or_else(|| "127.0.0.1".into()) - }; - let pac_port = IVerge::get_singleton_port(); - Autoproxy { - enable: true, - url: format!("http://{proxy_host}:{pac_port}/commands/pac"), - } - } - - async fn get_expected_sys_proxy() -> Sysproxy { - use crate::constants::network; - - let (verge_mixed_port, proxy_host) = { - let verge_config = Config::verge().await; - let verge_ref = verge_config.latest_arc(); - (verge_ref.verge_mixed_port, verge_ref.proxy_host.clone()) - }; - - let default_port = { - let clash_config = Config::clash().await; - clash_config.latest_arc().get_mixed_port() - }; - - let port = verge_mixed_port.unwrap_or(default_port); - let host = proxy_host - .unwrap_or_else(|| network::DEFAULT_PROXY_HOST.into()) - .into(); - - Sysproxy { - enable: true, - host, - port, - bypass: Self::get_bypass_config().await.into(), - } - } - - async fn get_bypass_config() -> String { - use crate::constants::bypass; - - let verge_config = Config::verge().await; - let verge = verge_config.latest_arc(); - let use_default = verge.use_default_bypass.unwrap_or(true); - let custom = verge.system_proxy_bypass.as_deref().unwrap_or(""); - - match (use_default, custom.is_empty()) { - (_, true) => bypass::DEFAULT.into(), - (true, false) => format!("{},{}", bypass::DEFAULT, custom).into(), - (false, false) => custom.into(), - } - } - - #[cfg(target_os = "windows")] - async fn restore_pac_proxy(expected_url: &str) -> Result<(), anyhow::Error> { - if handle::Handle::global().is_exiting() { - logging!(debug, Type::Network, "应用正在退出,跳过PAC代理恢复"); - return Ok(()); - } - Self::execute_sysproxy_command(&["pac", expected_url]).await - } - - #[allow(clippy::unused_async)] - #[cfg(not(target_os = "windows"))] - async fn restore_pac_proxy(expected_url: &str) -> Result<(), anyhow::Error> { - { - let new_autoproxy = Autoproxy { - enable: true, - url: expected_url.to_string(), - }; - // logging_error!(Type::System, true, new_autoproxy.set_auto_proxy()); - new_autoproxy - .set_auto_proxy() - .map_err(|e| anyhow::anyhow!("Failed to set auto proxy: {}", e)) - } - } - - #[cfg(target_os = "windows")] - async fn restore_sys_proxy(expected: &Sysproxy) -> Result<(), anyhow::Error> { - if handle::Handle::global().is_exiting() { - logging!(debug, Type::Network, "应用正在退出,跳过系统代理恢复"); - return Ok(()); - } - let address = format!("{}:{}", expected.host, expected.port); - Self::execute_sysproxy_command(&["global", &address, &expected.bypass]).await - } - - #[allow(clippy::unused_async)] - #[cfg(not(target_os = "windows"))] - async fn restore_sys_proxy(expected: &Sysproxy) -> Result<(), anyhow::Error> { - { - // logging_error!(Type::System, true, expected.set_system_proxy()); - expected - .set_system_proxy() - .map_err(|e| anyhow::anyhow!("Failed to set system proxy: {}", e)) - } - } - - #[cfg(target_os = "windows")] - async fn execute_sysproxy_command(args: &[&str]) -> Result<(), anyhow::Error> { - if handle::Handle::global().is_exiting() { - logging!( - debug, - Type::Network, - "应用正在退出,取消调用 sysproxy.exe,参数: {:?}", - args - ); - return Ok(()); - } - - use crate::utils::dirs; - #[allow(unused_imports)] // creation_flags必须 - use std::os::windows::process::CommandExt as _; - use tokio::process::Command; - - let binary_path = match dirs::service_path() { - Ok(path) => path, - Err(e) => { - logging!(error, Type::Network, "获取服务路径失败: {e}"); - return Err(e); - } - }; - - let sysproxy_exe = binary_path.with_file_name("sysproxy.exe"); - if !sysproxy_exe.exists() { - logging!(error, Type::Network, "sysproxy.exe 不存在"); - } - anyhow::ensure!(sysproxy_exe.exists(), "sysproxy.exe does not exist"); - - let _output = Command::new(sysproxy_exe) - .args(args) - .creation_flags(0x08000000) // CREATE_NO_WINDOW - 隐藏窗口 - .output() - .await?; - - Ok(()) - } -} diff --git a/src-tauri/src/core/mod.rs b/src-tauri/src/core/mod.rs index 6bdb2418b..9dc578796 100644 --- a/src-tauri/src/core/mod.rs +++ b/src-tauri/src/core/mod.rs @@ -1,6 +1,4 @@ -pub mod async_proxy_query; pub mod backup; -pub mod event_driven_proxy; pub mod handle; pub mod hotkey; pub mod logger; @@ -13,4 +11,4 @@ pub mod tray; pub mod validate; pub mod win_uwp; -pub use self::{event_driven_proxy::EventDrivenProxyManager, manager::CoreManager, timer::Timer}; +pub use self::{manager::CoreManager, timer::Timer}; diff --git a/src-tauri/src/core/sysopt.rs b/src-tauri/src/core/sysopt.rs index e9e1ade55..6af30efd1 100644 --- a/src-tauri/src/core/sysopt.rs +++ b/src-tauri/src/core/sysopt.rs @@ -2,22 +2,43 @@ use crate::utils::autostart as startup_shortcut; use crate::{ config::{Config, IVerge}, - core::{EventDrivenProxyManager, handle::Handle}, + core::handle::Handle, logging, logging_error, singleton_lazy, utils::logging::Type, }; use anyhow::Result; +use parking_lot::RwLock; use scopeguard::defer; use smartstring::alias::String; -use std::sync::atomic::{AtomicBool, Ordering}; -#[cfg(not(target_os = "windows"))] -use sysproxy::{Autoproxy, Sysproxy}; +use std::{ + sync::{ + Arc, + atomic::{AtomicBool, Ordering}, + }, + time::Duration, +}; +use sysproxy::{Autoproxy, GuardMonitor, GuardType, Sysproxy}; use tauri_plugin_autostart::ManagerExt as _; pub struct Sysopt { initialed: AtomicBool, update_sysproxy: AtomicBool, reset_sysproxy: AtomicBool, + guard: Arc>, +} + +impl Default for Sysopt { + fn default() -> Self { + Self { + initialed: AtomicBool::new(false), + update_sysproxy: AtomicBool::new(false), + reset_sysproxy: AtomicBool::new(false), + guard: Arc::new(RwLock::new(GuardMonitor::new( + GuardType::None, + Duration::from_secs(30), + ))), + } + } } #[cfg(target_os = "windows")] @@ -82,16 +103,6 @@ async fn execute_sysproxy_command(args: Vec) -> Result<()> Ok(()) } -impl Default for Sysopt { - fn default() -> Self { - Self { - initialed: AtomicBool::new(false), - update_sysproxy: AtomicBool::new(false), - reset_sysproxy: AtomicBool::new(false), - } - } -} - // Use simplified singleton_lazy macro singleton_lazy!(Sysopt, SYSOPT, Sysopt::default); @@ -100,30 +111,64 @@ impl Sysopt { self.initialed.load(Ordering::SeqCst) } - pub fn init_guard_sysproxy(&self) { - // 使用事件驱动代理管理器 - let proxy_manager = EventDrivenProxyManager::global(); - proxy_manager.notify_app_started(); + fn access_guard(&self) -> Arc> { + Arc::clone(&self.guard) + } - logging!(info, Type::Core, "已启用事件驱动代理守卫"); + 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) { + logging!(info, Type::Core, "System proxy is disabled."); + self.access_guard().write().stop(); + return; + } + if !verge.enable_proxy_guard.unwrap_or(false) { + logging!(info, Type::Core, "System proxy guard is disabled."); + return; + } + logging!( + info, + Type::Core, + "Updating system proxy with duration: {} seconds", + verge.proxy_guard_duration.unwrap_or(30) + ); + { + let guard = self.access_guard(); + guard.write().set_interval(Duration::from_secs( + verge.proxy_guard_duration.unwrap_or(30), + )); + } + logging!(info, Type::Core, "Starting system proxy guard..."); + { + let guard = self.access_guard(); + guard.write().start(); + } } /// init the sysproxy pub async fn update_sysproxy(&self) -> Result<()> { self.initialed.store(true, Ordering::SeqCst); + if self.update_sysproxy.load(Ordering::Acquire) { + logging!(info, Type::Core, "Sysproxy update is already in progress."); + return Ok(()); + } if self .update_sysproxy - .compare_exchange(false, true, Ordering::SeqCst, Ordering::SeqCst) + .compare_exchange(false, true, Ordering::AcqRel, Ordering::Acquire) .is_err() { + logging!(info, Type::Core, "Sysproxy update is already in progress."); return Ok(()); } defer! { - self.update_sysproxy.store(false, Ordering::SeqCst); + logging!(info, Type::Core, "Sysproxy update completed."); + self.update_sysproxy.store(false, Ordering::Release); } + let verge = Config::verge().await.latest_arc(); let port = { - let verge_port = Config::verge().await.latest_arc().verge_mixed_port; + let verge_port = verge.verge_mixed_port; match verge_port { Some(port) => port, None => Config::clash().await.latest_arc().get_mixed_port(), @@ -132,8 +177,6 @@ impl Sysopt { let pac_port = IVerge::get_singleton_port(); let (sys_enable, pac_enable, proxy_host) = { - let verge = Config::verge().await; - let verge = verge.latest_arc(); ( verge.enable_system_proxy.unwrap_or(false), verge.proxy_auto_config.unwrap_or(false), @@ -160,8 +203,9 @@ impl Sysopt { if !sys_enable { sys.set_system_proxy()?; auto.set_auto_proxy()?; - let proxy_manager = EventDrivenProxyManager::global(); - proxy_manager.notify_config_changed(); + self.access_guard() + .write() + .set_guard_type(GuardType::Sysproxy(sys)); return Ok(()); } @@ -170,8 +214,9 @@ impl Sysopt { auto.enable = true; sys.set_system_proxy()?; auto.set_auto_proxy()?; - let proxy_manager = EventDrivenProxyManager::global(); - proxy_manager.notify_config_changed(); + self.access_guard() + .write() + .set_guard_type(GuardType::Autoproxy(auto)); return Ok(()); } @@ -180,33 +225,47 @@ impl Sysopt { sys.enable = true; auto.set_auto_proxy()?; sys.set_system_proxy()?; - let proxy_manager = EventDrivenProxyManager::global(); - proxy_manager.notify_config_changed(); + self.access_guard() + .write() + .set_guard_type(GuardType::Sysproxy(sys)); return Ok(()); } } + #[cfg(target_os = "windows")] { if !sys_enable { - let result = self.reset_sysproxy().await; - let proxy_manager = EventDrivenProxyManager::global(); - proxy_manager.notify_config_changed(); - return result; + self.access_guard().write().set_guard_type(GuardType::None); + return self.reset_sysproxy().await; } - let args: Vec = if pac_enable { + let (args, guard_type): (Vec, GuardType) = if pac_enable { let address = format!("http://{proxy_host}:{pac_port}/commands/pac"); - vec!["pac".into(), address] + ( + vec!["pac".into(), address.clone()], + GuardType::Autoproxy(Autoproxy { + enable: true, + url: address, + }), + ) } else { let address = format!("{proxy_host}:{port}"); let bypass = get_bypass().await; - vec!["global".into(), address, bypass.into()] + 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); } - let proxy_manager = EventDrivenProxyManager::global(); - proxy_manager.notify_config_changed(); Ok(()) } diff --git a/src-tauri/src/feat/config.rs b/src-tauri/src/feat/config.rs index cfa9aef00..a127a5bb1 100644 --- a/src-tauri/src/feat/config.rs +++ b/src-tauri/src/feat/config.rs @@ -1,7 +1,7 @@ use crate::{ config::{Config, IVerge}, core::{CoreManager, handle, hotkey, sysopt, tray}, - logging_error, + logging, logging_error, module::{auto_backup::AutoBackupManager, lightweight}, utils::{draft::SharedBox, logging::Type}, }; @@ -107,6 +107,8 @@ fn determine_update_flags(patch: &IVerge) -> i32 { let enable_auto_light_weight = patch.enable_auto_light_weight_mode; let enable_external_controller = patch.enable_external_controller; let tray_inline_proxy_groups = patch.tray_inline_proxy_groups; + let enable_proxy_guard = patch.enable_proxy_guard; + let proxy_guard_duration = patch.proxy_guard_duration; if tun_mode.is_some() { update_flags |= UpdateFlags::ClashConfig as i32; @@ -144,7 +146,12 @@ fn determine_update_flags(patch: &IVerge) -> i32 { update_flags |= UpdateFlags::SystrayIcon as i32; } - if proxy_bypass.is_some() || pac_content.is_some() || pac.is_some() { + if proxy_bypass.is_some() + || pac_content.is_some() + || pac.is_some() + || enable_proxy_guard.is_some() + || proxy_guard_duration.is_some() + { update_flags |= UpdateFlags::SysProxy as i32; } @@ -207,6 +214,7 @@ async fn process_terminated_flags(update_flags: i32, patch: &IVerge) -> Result<( } if (update_flags & (UpdateFlags::SysProxy as i32)) != 0 { sysopt::Sysopt::global().update_sysproxy().await?; + sysopt::Sysopt::global().refresh_guard().await; } if (update_flags & (UpdateFlags::Hotkey as i32)) != 0 && let Some(hotkeys) = &patch.hotkeys @@ -258,6 +266,7 @@ pub async fn patch_verge(patch: &IVerge, not_save_file: bool) -> Result<()> { if !not_save_file { // 分离数据获取和异步调用 let verge_data = Config::verge().await.data_arc(); + logging!(info, Type::Setup, "Saving Verge configuration to file..."); verge_data.save_file().await?; } Ok(()) diff --git a/src-tauri/src/feat/window.rs b/src-tauri/src/feat/window.rs index 876ba4432..9e741258d 100644 --- a/src-tauri/src/feat/window.rs +++ b/src-tauri/src/feat/window.rs @@ -1,5 +1,4 @@ use crate::config::Config; -use crate::core::event_driven_proxy::EventDrivenProxyManager; use crate::core::{CoreManager, handle, sysopt}; use crate::utils; use crate::utils::window_manager::WindowManager; @@ -24,7 +23,6 @@ pub async fn quit() { // 获取应用句柄并设置退出标志 let app_handle = handle::Handle::app_handle(); handle::Handle::global().set_is_exiting(); - EventDrivenProxyManager::global().notify_app_stopping(); logging!(info, Type::System, "开始异步清理资源"); let cleanup_result = clean_async().await; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 365afc15a..e55613c5b 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -14,7 +14,7 @@ use crate::constants::files; #[cfg(target_os = "linux")] use crate::utils::linux; use crate::{ - core::{EventDrivenProxyManager, handle}, + core::handle, process::AsyncHandler, utils::{resolve, server}, }; @@ -440,7 +440,6 @@ pub fn run() { let handle = core::handle::Handle::global(); if !handle.is_exiting() { handle.set_is_exiting(); - EventDrivenProxyManager::global().notify_app_stopping(); feat::clean(); } } diff --git a/src-tauri/src/utils/resolve/mod.rs b/src-tauri/src/utils/resolve/mod.rs index 40971b0b4..6da25a439 100644 --- a/src-tauri/src/utils/resolve/mod.rs +++ b/src-tauri/src/utils/resolve/mod.rs @@ -54,7 +54,7 @@ pub fn resolve_setup_async() { init_service_manager().await; init_core_manager().await; init_system_proxy().await; - AsyncHandler::spawn_blocking(init_system_proxy_guard); + init_system_proxy_guard().await; }); let tray_init = async { @@ -173,8 +173,8 @@ pub(super) async fn init_system_proxy() { ); } -pub(super) fn init_system_proxy_guard() { - sysopt::Sysopt::global().init_guard_sysproxy(); +pub(super) async fn init_system_proxy_guard() { + sysopt::Sysopt::global().refresh_guard().await; } pub(super) async fn refresh_tray_menu() {