fixed an issue with error 0xc00000142

This commit is contained in:
coolcoala
2025-11-12 23:28:49 +03:00
parent aba9715453
commit 1aa0c7bc34
4 changed files with 97 additions and 2 deletions

View File

@@ -4,7 +4,7 @@ use tokio::sync::{mpsc, oneshot};
use tokio::time::{sleep, timeout, Duration}; use tokio::time::{sleep, timeout, Duration};
use crate::config::{Config, IVerge}; 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::logging_error;
use crate::utils::logging::Type; use crate::utils::logging::Type;
use once_cell::sync::Lazy; use once_cell::sync::Lazy;
@@ -231,6 +231,11 @@ impl EventDrivenProxyManager {
} }
ProxyEvent::AppStopping => { ProxyEvent::AppStopping => {
log::info!(target: "app", "Cleaning up proxy state"); 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<RwLock<ProxyState>>) { async fn check_and_restore_proxy(state: &Arc<RwLock<ProxyState>>) {
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 (sys_enabled, pac_enabled) = {
let s = state.read(); let s = state.read();
(s.sys_enabled, s.pac_enabled) (s.sys_enabled, s.pac_enabled)
@@ -298,6 +307,11 @@ impl EventDrivenProxyManager {
} }
async fn check_and_restore_pac_proxy(state: &Arc<RwLock<ProxyState>>) { async fn check_and_restore_pac_proxy(state: &Arc<RwLock<ProxyState>>) {
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 current = Self::get_auto_proxy_with_timeout().await;
let expected = Self::get_expected_pac_config(); let expected = Self::get_expected_pac_config();
@@ -320,6 +334,11 @@ impl EventDrivenProxyManager {
} }
async fn check_and_restore_sys_proxy(state: &Arc<RwLock<ProxyState>>) { async fn check_and_restore_sys_proxy(state: &Arc<RwLock<ProxyState>>) {
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 current = Self::get_sys_proxy_with_timeout().await;
let expected = Self::get_expected_sys_proxy(); let expected = Self::get_expected_sys_proxy();
@@ -344,6 +363,11 @@ impl EventDrivenProxyManager {
} }
async fn enable_system_proxy(state: &Arc<RwLock<ProxyState>>) { async fn enable_system_proxy(state: &Arc<RwLock<ProxyState>>) {
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"); log::info!(target: "app", "Enabling system proxy");
let pac_enabled = state.read().pac_enabled; let pac_enabled = state.read().pac_enabled;
@@ -373,6 +397,11 @@ impl EventDrivenProxyManager {
} }
async fn switch_proxy_mode(state: &Arc<RwLock<ProxyState>>, to_pac: bool) { async fn switch_proxy_mode(state: &Arc<RwLock<ProxyState>>, 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" }); log::info!(target: "app", "Switching to {} mode", if to_pac { "PAC" } else { "HTTP Proxy" });
if to_pac { if to_pac {
@@ -507,6 +536,10 @@ impl EventDrivenProxyManager {
#[cfg(target_os = "windows")] #[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; Self::execute_sysproxy_command(&["pac", expected_url]).await;
} }
} }
@@ -519,6 +552,10 @@ impl EventDrivenProxyManager {
#[cfg(target_os = "windows")] #[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); let address = format!("{}:{}", expected.host, expected.port);
Self::execute_sysproxy_command(&["global", &address, &expected.bypass]).await; Self::execute_sysproxy_command(&["global", &address, &expected.bypass]).await;
} }
@@ -526,6 +563,15 @@ impl EventDrivenProxyManager {
#[cfg(target_os = "windows")] #[cfg(target_os = "windows")]
async fn execute_sysproxy_command(args: &[&str]) { 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; use crate::utils::dirs;
#[allow(unused_imports)] // creation_flags必须 #[allow(unused_imports)] // creation_flags必须
use std::os::windows::process::CommandExt; use std::os::windows::process::CommandExt;

View File

@@ -69,6 +69,10 @@ impl Sysopt {
/// init the sysproxy /// init the sysproxy
pub async fn update_sysproxy(&self) -> Result<()> { 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 _lock = self.update_sysproxy.lock().await;
let port = Config::verge() let port = Config::verge()
@@ -185,6 +189,10 @@ impl Sysopt {
/// reset the sysproxy /// reset the sysproxy
pub async fn reset_sysproxy(&self) -> Result<()> { 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; let _lock = self.reset_sysproxy.lock().await;
//直接关闭所有代理 //直接关闭所有代理
#[cfg(not(target_os = "windows"))] #[cfg(not(target_os = "windows"))]

View File

@@ -184,11 +184,19 @@ impl Tray {
} }
pub fn init(&self) -> Result<()> { pub fn init(&self) -> Result<()> {
if handle::Handle::global().is_exiting() {
log::debug!(target: "app", "Application is exiting, skip tray initialization");
return Ok(());
}
Ok(()) Ok(())
} }
/// 更新托盘点击行为 /// 更新托盘点击行为
pub fn update_click_behavior(&self) -> Result<()> { 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 app_handle = handle::Handle::global().app_handle().unwrap();
let tray_event = { Config::verge().latest().tray_event.clone() }; let tray_event = { Config::verge().latest().tray_event.clone() };
let tray_event: String = tray_event.unwrap_or("main_window".into()); let tray_event: String = tray_event.unwrap_or("main_window".into());
@@ -202,6 +210,10 @@ impl Tray {
/// 更新托盘菜单 /// 更新托盘菜单
pub fn update_menu(&self) -> Result<()> { 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); const MIN_UPDATE_INTERVAL: Duration = Duration::from_millis(100);
@@ -291,6 +303,10 @@ impl Tray {
/// 更新托盘图标 /// 更新托盘图标
#[cfg(target_os = "macos")] #[cfg(target_os = "macos")]
pub fn update_icon(&self, _rate: Option<Rate>) -> Result<()> { pub fn update_icon(&self, _rate: Option<Rate>) -> 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() { let app_handle = match handle::Handle::global().app_handle() {
Some(handle) => handle, Some(handle) => handle,
None => { None => {
@@ -328,6 +344,10 @@ impl Tray {
#[cfg(not(target_os = "macos"))] #[cfg(not(target_os = "macos"))]
pub fn update_icon(&self, _rate: Option<Rate>) -> Result<()> { pub fn update_icon(&self, _rate: Option<Rate>) -> 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() { let app_handle = match handle::Handle::global().app_handle() {
Some(handle) => handle, Some(handle) => handle,
None => { None => {
@@ -361,6 +381,10 @@ impl Tray {
/// 更新托盘显示状态的函数 /// 更新托盘显示状态的函数
pub fn update_tray_display(&self) -> Result<()> { 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 app_handle = handle::Handle::global().app_handle().unwrap();
let _tray = app_handle.tray_by_id("main").unwrap(); let _tray = app_handle.tray_by_id("main").unwrap();
@@ -372,6 +396,10 @@ impl Tray {
/// 更新托盘提示 /// 更新托盘提示
pub fn update_tooltip(&self) -> Result<()> { 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() { let app_handle = match handle::Handle::global().app_handle() {
Some(handle) => handle, Some(handle) => handle,
None => { None => {
@@ -429,6 +457,10 @@ impl Tray {
} }
pub fn update_part(&self) -> Result<()> { 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_menu()?;
self.update_icon(None)?; self.update_icon(None)?;
self.update_tooltip()?; self.update_tooltip()?;
@@ -442,6 +474,10 @@ impl Tray {
pub fn unsubscribe_traffic(&self) {} pub fn unsubscribe_traffic(&self) {}
pub fn create_tray_from_handle(&self, app_handle: &AppHandle) -> Result<()> { 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"); log::info!(target: "app", "Creating system tray from AppHandle");
// 获取图标 // 获取图标
@@ -509,6 +545,10 @@ impl Tray {
// 托盘统一的状态更新函数 // 托盘统一的状态更新函数
pub fn update_all_states(&self) -> Result<()> { 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_menu()?;
self.update_icon(None)?; self.update_icon(None)?;

View File

@@ -2,7 +2,7 @@
use crate::AppHandleManager; use crate::AppHandleManager;
use crate::{ use crate::{
config::Config, config::Config,
core::{handle, sysopt, CoreManager}, core::{event_driven_proxy::EventDrivenProxyManager, handle, sysopt, CoreManager},
logging, logging,
module::mihomo::MihomoManager, module::mihomo::MihomoManager,
utils::logging::Type, utils::logging::Type,
@@ -69,6 +69,7 @@ pub fn quit() {
// 获取应用句柄并设置退出标志 // 获取应用句柄并设置退出标志
let app_handle = handle::Handle::global().app_handle().unwrap(); let app_handle = handle::Handle::global().app_handle().unwrap();
handle::Handle::global().set_is_exiting(); handle::Handle::global().set_is_exiting();
EventDrivenProxyManager::global().notify_app_stopping();
// 优先关闭窗口,提供立即反馈 // 优先关闭窗口,提供立即反馈
if let Some(window) = handle::Handle::global().get_window() { if let Some(window) = handle::Handle::global().get_window() {