mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2026-02-10 11:40:28 +08:00
fix: resolve tun crash caused by single instance lock conflict on admin restart
This commit is contained in:
parent
e21558ac37
commit
2cfcf8be66
@ -261,7 +261,6 @@ export async function restartAsAdmin(forTun: boolean = true): Promise<void> {
|
|||||||
const { stopCore } = await import('./manager')
|
const { stopCore } = await import('./manager')
|
||||||
managerLogger.info('Stopping core before admin restart...')
|
managerLogger.info('Stopping core before admin restart...')
|
||||||
await stopCore(true)
|
await stopCore(true)
|
||||||
// 等待 Core 完全停止
|
|
||||||
await new Promise((resolve) => setTimeout(resolve, 500))
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
managerLogger.warn('Failed to stop core before restart:', error)
|
managerLogger.warn('Failed to stop core before restart:', error)
|
||||||
@ -274,27 +273,18 @@ export async function restartAsAdmin(forTun: boolean = true): Promise<void> {
|
|||||||
const escapedExePath = exePath.replace(/'/g, "''")
|
const escapedExePath = exePath.replace(/'/g, "''")
|
||||||
const argsString = restartArgs.map((arg) => arg.replace(/'/g, "''")).join("', '")
|
const argsString = restartArgs.map((arg) => arg.replace(/'/g, "''")).join("', '")
|
||||||
|
|
||||||
|
// 使用 Start-Sleep 延迟启动,确保旧进程完全退出后再启动新进程
|
||||||
const command =
|
const command =
|
||||||
restartArgs.length > 0
|
restartArgs.length > 0
|
||||||
? `powershell -NoProfile -Command "Start-Process -FilePath '${escapedExePath}' -ArgumentList '${argsString}' -Verb RunAs -Wait:$false; exit 0"`
|
? `powershell -NoProfile -Command "Start-Sleep -Milliseconds 1000; Start-Process -FilePath '${escapedExePath}' -ArgumentList '${argsString}' -Verb RunAs"`
|
||||||
: `powershell -NoProfile -Command "Start-Process -FilePath '${escapedExePath}' -Verb RunAs -Wait:$false; exit 0"`
|
: `powershell -NoProfile -Command "Start-Sleep -Milliseconds 1000; Start-Process -FilePath '${escapedExePath}' -Verb RunAs"`
|
||||||
|
|
||||||
managerLogger.info('Restarting as administrator with command', command)
|
managerLogger.info('Restarting as administrator with command', command)
|
||||||
|
|
||||||
return new Promise((resolve, reject) => {
|
// 先启动 PowerShell(它会等待 1 秒),然后立即退出当前进程
|
||||||
exec(command, { windowsHide: true }, (error, _stdout, stderr) => {
|
exec(command, { windowsHide: true })
|
||||||
if (error) {
|
managerLogger.info('PowerShell command started, quitting app immediately')
|
||||||
managerLogger.error('PowerShell execution error', error)
|
app.exit(0)
|
||||||
managerLogger.error('stderr', stderr)
|
|
||||||
reject(new Error(`Failed to restart as administrator: ${error.message}`))
|
|
||||||
return
|
|
||||||
}
|
|
||||||
managerLogger.info('PowerShell command executed successfully, quitting app')
|
|
||||||
// 立即退出,避免竞态
|
|
||||||
app.quit()
|
|
||||||
resolve()
|
|
||||||
})
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
|
|
||||||
export async function requestTunPermissions(): Promise<void> {
|
export async function requestTunPermissions(): Promise<void> {
|
||||||
|
|||||||
@ -189,8 +189,17 @@ 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') {
|
// EPERM/EBUSY: 文件被占用;ENOENT: unlink 时目标不存在(Windows cp force 模式的边界情况)
|
||||||
await initLogger.warn(`Skipping ${file}: file is in use`)
|
if (code === 'EPERM' || code === 'EBUSY' || code === 'ENOENT') {
|
||||||
|
await initLogger.warn(`Skipping ${file}: ${code}`)
|
||||||
|
// 如果目标文件已存在,跳过即可;否则尝试不带 force 复制
|
||||||
|
if (!existsSync(targetPath)) {
|
||||||
|
try {
|
||||||
|
await cp(sourcePath, targetPath, { recursive: true })
|
||||||
|
} catch {
|
||||||
|
await initLogger.warn(`Retry copy ${file} also failed`)
|
||||||
|
}
|
||||||
|
}
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
throw error
|
throw error
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user