fix(client): 托盘「退出」崩溃(0xC000041D)——绕开 windowManager.destroy()
Windows 上从托盘菜单退出会崩:windowManager.destroy() 在 Win32 托盘回调里触发 DestroyWindow/WM_CLOSE 回调链(并回调 onWindowClose → await isPreventClose), 异常穿过内核回调边界 → STATUS_FATAL_USER_CALLBACK_EXCEPTION(0xC000041D), flutter_windows.dll 处崩溃。WER 崩溃签名跨版本一致(自 1.0.0 起),非业务代码引入。 内核已在 onBeforeQuit 停掉、隧道已拆,改为先 trayManager.destroy() 摘图标, 再 exit(0) 干净退出进程,绕开原生窗口销毁回调链。 Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -86,8 +86,14 @@ class TrayService with TrayListener, WindowListener {
|
||||
case 'quit':
|
||||
// 退出前先停内核拆隧道(避免 sudo sing-box 孤儿 + TUN 残留)。
|
||||
await onBeforeQuit?.call();
|
||||
await windowManager.setPreventClose(false);
|
||||
await windowManager.destroy();
|
||||
// 不要用 windowManager.destroy():它在托盘回调里触发 DestroyWindow/WM_CLOSE
|
||||
// 回调链(还会回调 onWindowClose → await isPreventClose),异常穿过 Win32 回调
|
||||
// 边界 → 0xC000041D(STATUS_FATAL_USER_CALLBACK_EXCEPTION)崩溃。内核已停、隧道
|
||||
// 已拆,先摘掉托盘图标避免残留,再直接干净退出进程。
|
||||
try {
|
||||
await trayManager.destroy();
|
||||
} catch (_) {}
|
||||
exit(0);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user