diff --git a/src-tauri/src/core/event_driven_proxy.rs b/src-tauri/src/core/event_driven_proxy.rs index 240e9a73..805ba74a 100644 --- a/src-tauri/src/core/event_driven_proxy.rs +++ b/src-tauri/src/core/event_driven_proxy.rs @@ -4,7 +4,7 @@ use tokio::sync::{mpsc, oneshot}; use tokio::time::{sleep, timeout, Duration}; use crate::config::{Config, IVerge}; -use crate::core::async_proxy_query::AsyncProxyQuery; +use crate::core::{async_proxy_query::AsyncProxyQuery, handle}; use crate::logging_error; use crate::utils::logging::Type; use once_cell::sync::Lazy; @@ -231,6 +231,11 @@ impl EventDrivenProxyManager { } ProxyEvent::AppStopping => { log::info!(target: "app", "Cleaning up proxy state"); + Self::update_state_timestamp(state, |s| { + s.sys_enabled = false; + s.pac_enabled = false; + s.is_healthy = false; + }); } } } @@ -279,6 +284,10 @@ impl EventDrivenProxyManager { } async fn check_and_restore_proxy(state: &Arc>) { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip system proxy guard check"); + return; + } let (sys_enabled, pac_enabled) = { let s = state.read(); (s.sys_enabled, s.pac_enabled) @@ -298,6 +307,11 @@ impl EventDrivenProxyManager { } async fn check_and_restore_pac_proxy(state: &Arc>) { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip PAC proxy restore check"); + return; + } + let current = Self::get_auto_proxy_with_timeout().await; let expected = Self::get_expected_pac_config(); @@ -320,6 +334,11 @@ impl EventDrivenProxyManager { } async fn check_and_restore_sys_proxy(state: &Arc>) { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip system proxy restore check"); + return; + } + let current = Self::get_sys_proxy_with_timeout().await; let expected = Self::get_expected_sys_proxy(); @@ -344,6 +363,11 @@ impl EventDrivenProxyManager { } async fn enable_system_proxy(state: &Arc>) { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip enabling system proxy"); + return; + } + log::info!(target: "app", "Enabling system proxy"); let pac_enabled = state.read().pac_enabled; @@ -373,6 +397,11 @@ impl EventDrivenProxyManager { } async fn switch_proxy_mode(state: &Arc>, to_pac: bool) { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip proxy mode switch"); + return; + } + log::info!(target: "app", "Switching to {} mode", if to_pac { "PAC" } else { "HTTP Proxy" }); if to_pac { @@ -507,6 +536,10 @@ impl EventDrivenProxyManager { #[cfg(target_os = "windows")] { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip PAC proxy restore"); + return; + } Self::execute_sysproxy_command(&["pac", expected_url]).await; } } @@ -519,6 +552,10 @@ impl EventDrivenProxyManager { #[cfg(target_os = "windows")] { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip system proxy restore"); + return; + } let address = format!("{}:{}", expected.host, expected.port); Self::execute_sysproxy_command(&["global", &address, &expected.bypass]).await; } @@ -526,6 +563,15 @@ impl EventDrivenProxyManager { #[cfg(target_os = "windows")] async fn execute_sysproxy_command(args: &[&str]) { + if handle::Handle::global().is_exiting() { + log::debug!( + target: "app", + "Application is exiting, cancel calling sysproxy.exe, args: {:?}", + args + ); + return; + } + use crate::utils::dirs; #[allow(unused_imports)] // creation_flags必须 use std::os::windows::process::CommandExt; diff --git a/src-tauri/src/core/sysopt.rs b/src-tauri/src/core/sysopt.rs index 350570d8..8a08984a 100644 --- a/src-tauri/src/core/sysopt.rs +++ b/src-tauri/src/core/sysopt.rs @@ -69,6 +69,10 @@ impl Sysopt { /// init the sysproxy pub async fn update_sysproxy(&self) -> Result<()> { + if Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip updating sysproxy"); + return Ok(()); + } let _lock = self.update_sysproxy.lock().await; let port = Config::verge() @@ -185,6 +189,10 @@ impl Sysopt { /// reset the sysproxy pub async fn reset_sysproxy(&self) -> Result<()> { + if Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip resetting sysproxy"); + return Ok(()); + } let _lock = self.reset_sysproxy.lock().await; //直接关闭所有代理 #[cfg(not(target_os = "windows"))] diff --git a/src-tauri/src/core/tray/mod.rs b/src-tauri/src/core/tray/mod.rs index c4e19970..de422d17 100644 --- a/src-tauri/src/core/tray/mod.rs +++ b/src-tauri/src/core/tray/mod.rs @@ -184,11 +184,19 @@ impl Tray { } pub fn init(&self) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray initialization"); + return Ok(()); + } Ok(()) } /// 更新托盘点击行为 pub fn update_click_behavior(&self) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray click behavior update"); + return Ok(()); + } let app_handle = handle::Handle::global().app_handle().unwrap(); let tray_event = { Config::verge().latest().tray_event.clone() }; let tray_event: String = tray_event.unwrap_or("main_window".into()); @@ -202,6 +210,10 @@ impl Tray { /// 更新托盘菜单 pub fn update_menu(&self) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray menu update"); + return Ok(()); + } // 调整最小更新间隔,确保状态及时刷新 const MIN_UPDATE_INTERVAL: Duration = Duration::from_millis(100); @@ -291,6 +303,10 @@ impl Tray { /// 更新托盘图标 #[cfg(target_os = "macos")] pub fn update_icon(&self, _rate: Option) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray icon update"); + return Ok(()); + } let app_handle = match handle::Handle::global().app_handle() { Some(handle) => handle, None => { @@ -328,6 +344,10 @@ impl Tray { #[cfg(not(target_os = "macos"))] pub fn update_icon(&self, _rate: Option) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray icon update"); + return Ok(()); + } let app_handle = match handle::Handle::global().app_handle() { Some(handle) => handle, None => { @@ -361,6 +381,10 @@ impl Tray { /// 更新托盘显示状态的函数 pub fn update_tray_display(&self) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray display update"); + return Ok(()); + } let app_handle = handle::Handle::global().app_handle().unwrap(); let _tray = app_handle.tray_by_id("main").unwrap(); @@ -372,6 +396,10 @@ impl Tray { /// 更新托盘提示 pub fn update_tooltip(&self) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray tooltip update"); + return Ok(()); + } let app_handle = match handle::Handle::global().app_handle() { Some(handle) => handle, None => { @@ -429,6 +457,10 @@ impl Tray { } pub fn update_part(&self) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray partial update"); + return Ok(()); + } self.update_menu()?; self.update_icon(None)?; self.update_tooltip()?; @@ -442,6 +474,10 @@ impl Tray { pub fn unsubscribe_traffic(&self) {} pub fn create_tray_from_handle(&self, app_handle: &AppHandle) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray creation"); + return Ok(()); + } log::info!(target: "app", "Creating system tray from AppHandle"); // 获取图标 @@ -509,6 +545,10 @@ impl Tray { // 托盘统一的状态更新函数 pub fn update_all_states(&self) -> Result<()> { + if handle::Handle::global().is_exiting() { + log::debug!(target: "app", "Application is exiting, skip tray state update"); + return Ok(()); + } // 确保所有状态更新完成 self.update_menu()?; self.update_icon(None)?; diff --git a/src-tauri/src/feat/window.rs b/src-tauri/src/feat/window.rs index f3f735e7..c0660ef4 100644 --- a/src-tauri/src/feat/window.rs +++ b/src-tauri/src/feat/window.rs @@ -2,7 +2,7 @@ use crate::AppHandleManager; use crate::{ config::Config, - core::{handle, sysopt, CoreManager}, + core::{event_driven_proxy::EventDrivenProxyManager, handle, sysopt, CoreManager}, logging, module::mihomo::MihomoManager, utils::logging::Type, @@ -69,6 +69,7 @@ pub fn quit() { // 获取应用句柄并设置退出标志 let app_handle = handle::Handle::global().app_handle().unwrap(); handle::Handle::global().set_is_exiting(); + EventDrivenProxyManager::global().notify_app_stopping(); // 优先关闭窗口,提供立即反馈 if let Some(window) = handle::Handle::global().get_window() {