fix: prevent crashes from process.exit, empty array destructuring and native module calls

This commit is contained in:
xmk23333 2026-01-15 23:44:28 +08:00
parent a28f576d78
commit 9e0f27aea3
6 changed files with 47 additions and 23 deletions

View File

@ -1,3 +1,11 @@
# 1.9.1
## 修复 (Fix)
- 修复 Windows 下以管理员重启开启 TUN 时因单实例锁冲突导致的闪退问题
- 修复托盘菜单开启 TUN 时管理员重启后继续执行导致的竞态问题
- 修复关键资源文件复制失败时静默跳过导致内核启动异常的问题
# 1.9.0 # 1.9.0
## 新功能 (Feat) ## 新功能 (Feat)

View File

@ -282,7 +282,11 @@ export async function restartAsAdmin(forTun: boolean = true): Promise<void> {
managerLogger.info('Restarting as administrator with command', command) managerLogger.info('Restarting as administrator with command', command)
// 先启动 PowerShell它会等待 1 秒),然后立即退出当前进程 // 先启动 PowerShell它会等待 1 秒),然后立即退出当前进程
exec(command, { windowsHide: true }) exec(command, { windowsHide: true }, (error) => {
if (error) {
managerLogger.error('Failed to start PowerShell for admin restart', error)
}
})
managerLogger.info('PowerShell command started, quitting app immediately') managerLogger.info('PowerShell command started, quitting app immediately')
app.exit(0) app.exit(0)
} }

View File

@ -87,13 +87,13 @@ async function checkHighPrivilegeCoreEarly(): Promise<void> {
if (choice === 0) { if (choice === 0) {
try { try {
await restartAsAdmin(false) await restartAsAdmin(false)
process.exit(0) app.exit(0)
} catch (error) { } catch (error) {
safeShowErrorBox('common.error.adminRequired', `${error}`) safeShowErrorBox('common.error.adminRequired', `${error}`)
process.exit(1) app.exit(1)
} }
} else { } else {
process.exit(0) app.exit(0)
} }
} catch (e) { } catch (e) {
mainLogger.error('Failed to check high privilege core', e) mainLogger.error('Failed to check high privilege core', e)
@ -151,12 +151,14 @@ app.whenReady().then(async () => {
try { try {
initCoreWatcher() initCoreWatcher()
const [startPromise] = await startCore() const startPromises = await startCore()
startPromise.then(async () => { if (startPromises.length > 0) {
await initProfileUpdater() startPromises[0].then(async () => {
await initWebdavBackupScheduler() await initProfileUpdater()
await checkAdminRestartForTun() await initWebdavBackupScheduler()
}) await checkAdminRestartForTun()
})
}
} catch (e) { } catch (e) {
safeShowErrorBox('mihomo.error.coreStartFailed', `${e}`) safeShowErrorBox('mihomo.error.coreStartFailed', `${e}`)
} }

View File

@ -253,6 +253,9 @@ export const buildContextMenu = async (): Promise<Menu> => {
} }
} catch (error) { } catch (error) {
await trayLogger.warn('Permission check failed in tray', error) await trayLogger.warn('Permission check failed in tray', error)
item.checked = false
ipcMain.emit('updateTrayMenu')
return
} }
await patchControledMihomoConfig({ tun: { enable }, dns: { enable: true } }) await patchControledMihomoConfig({ tun: { enable }, dns: { enable: true } })

View File

@ -97,10 +97,15 @@ async function enableSysProxy(): Promise<void> {
} }
} else { } else {
// Windows / Linux 直接使用 sysproxy-rs // Windows / Linux 直接使用 sysproxy-rs
if (mode === 'auto') { try {
triggerAutoProxy(true, `http://${proxyHost}:${pacPort}/pac`) if (mode === 'auto') {
} else { triggerAutoProxy(true, `http://${proxyHost}:${pacPort}/pac`)
triggerManualProxy(true, proxyHost, port, bypass.join(',')) } else {
triggerManualProxy(true, proxyHost, port, bypass.join(','))
}
} catch (error) {
await proxyLogger.error('Failed to enable system proxy', error)
throw error
} }
} }
} }
@ -114,8 +119,13 @@ async function disableSysProxy(): Promise<void> {
) )
} else { } else {
// Windows / Linux 直接使用 sysproxy-rs // Windows / Linux 直接使用 sysproxy-rs
triggerAutoProxy(false, '') try {
triggerManualProxy(false, '', 0, '') triggerAutoProxy(false, '')
triggerManualProxy(false, '', 0, '')
} catch (error) {
await proxyLogger.error('Failed to disable system proxy', error)
throw error
}
} }
} }

View File

@ -189,14 +189,11 @@ async function initFiles(): Promise<void> {
await cp(sourcePath, targetPath, { recursive: true, force: true }) await cp(sourcePath, targetPath, { recursive: true, force: true })
} catch (error: unknown) { } catch (error: unknown) {
const code = (error as NodeJS.ErrnoException).code const code = (error as NodeJS.ErrnoException).code
if (code === 'EPERM' || code === 'EBUSY') { // 文件被占用或权限问题,如果目标已存在则跳过
// 文件被占用,如果目标已存在则跳过 if ((code === 'EPERM' || code === 'EBUSY' || code === 'EACCES') && existsSync(targetPath)) {
if (existsSync(targetPath)) { await initLogger.warn(`Skipping ${file}: file is in use or permission denied`)
await initLogger.warn(`Skipping ${file}: file is in use`) return
return
}
} }
// 其他错误或目标不存在时,向上抛出让 criticalFiles 检查处理
throw error throw error
} }
}) })