mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2026-02-11 04:00:32 +08:00
fix: resolve auto-run and TUN restart issues on Windows IoT LTSC
This commit is contained in:
parent
bc4b59c66b
commit
295c4400e9
@ -256,8 +256,19 @@ export async function restartAsAdmin(forTun: boolean = true): Promise<void> {
|
|||||||
throw new Error('This function is only available on Windows')
|
throw new Error('This function is only available on Windows')
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// 先停止 Core,避免新旧进程冲突
|
||||||
|
try {
|
||||||
|
const { stopCore } = await import('./manager')
|
||||||
|
managerLogger.info('Stopping core before admin restart...')
|
||||||
|
await stopCore(true)
|
||||||
|
// 等待 Core 完全停止
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 500))
|
||||||
|
} catch (error) {
|
||||||
|
managerLogger.warn('Failed to stop core before restart:', error)
|
||||||
|
}
|
||||||
|
|
||||||
const exePath = process.execPath
|
const exePath = process.execPath
|
||||||
const args = process.argv.slice(1)
|
const args = process.argv.slice(1).filter((arg) => arg !== '--admin-restart-for-tun')
|
||||||
const restartArgs = forTun ? [...args, '--admin-restart-for-tun'] : args
|
const restartArgs = forTun ? [...args, '--admin-restart-for-tun'] : args
|
||||||
|
|
||||||
const escapedExePath = exePath.replace(/'/g, "''")
|
const escapedExePath = exePath.replace(/'/g, "''")
|
||||||
@ -279,7 +290,8 @@ export async function restartAsAdmin(forTun: boolean = true): Promise<void> {
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
managerLogger.info('PowerShell command executed successfully, quitting app')
|
managerLogger.info('PowerShell command executed successfully, quitting app')
|
||||||
setTimeout(() => app.quit(), 500)
|
// 立即退出,避免竞态
|
||||||
|
app.quit()
|
||||||
resolve()
|
resolve()
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|||||||
@ -56,10 +56,22 @@ function getTaskXml(asAdmin: boolean): string {
|
|||||||
export async function checkAutoRun(): Promise<boolean> {
|
export async function checkAutoRun(): Promise<boolean> {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
const execPromise = promisify(exec)
|
const execPromise = promisify(exec)
|
||||||
|
// 先检查任务计划程序
|
||||||
try {
|
try {
|
||||||
const { stdout } = await execPromise(
|
const { stdout } = await execPromise(
|
||||||
`chcp 437 && %SystemRoot%\\System32\\schtasks.exe /query /tn "${appName}"`
|
`chcp 437 && %SystemRoot%\\System32\\schtasks.exe /query /tn "${appName}"`
|
||||||
)
|
)
|
||||||
|
if (stdout.includes(appName)) {
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
} catch {
|
||||||
|
// 任务计划程序中不存在,继续检查注册表
|
||||||
|
}
|
||||||
|
|
||||||
|
// 检查注册表备用方案
|
||||||
|
try {
|
||||||
|
const regPath = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'
|
||||||
|
const { stdout } = await execPromise(`reg query "${regPath}" /v "${appName}"`)
|
||||||
return stdout.includes(appName)
|
return stdout.includes(appName)
|
||||||
} catch {
|
} catch {
|
||||||
return false
|
return false
|
||||||
@ -87,17 +99,45 @@ export async function enableAutoRun(): Promise<void> {
|
|||||||
const { checkAdminPrivileges } = await import('../core/manager')
|
const { checkAdminPrivileges } = await import('../core/manager')
|
||||||
const isAdmin = await checkAdminPrivileges()
|
const isAdmin = await checkAdminPrivileges()
|
||||||
await writeFile(taskFilePath, Buffer.from(`\ufeff${getTaskXml(isAdmin)}`, 'utf-16le'))
|
await writeFile(taskFilePath, Buffer.from(`\ufeff${getTaskXml(isAdmin)}`, 'utf-16le'))
|
||||||
|
|
||||||
|
let taskCreated = false
|
||||||
|
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
|
try {
|
||||||
await execPromise(
|
await execPromise(
|
||||||
`%SystemRoot%\\System32\\schtasks.exe /create /tn "${appName}" /xml "${taskFilePath}" /f`
|
`%SystemRoot%\\System32\\schtasks.exe /create /tn "${appName}" /xml "${taskFilePath}" /f`
|
||||||
)
|
)
|
||||||
|
taskCreated = true
|
||||||
|
} catch (error) {
|
||||||
|
await managerLogger.warn('Failed to create scheduled task as admin:', error)
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
try {
|
try {
|
||||||
await execPromise(
|
await execPromise(
|
||||||
`powershell -NoProfile -Command "Start-Process schtasks -Verb RunAs -ArgumentList '/create', '/tn', '${appName}', '/xml', '${taskFilePath}', '/f' -WindowStyle Hidden"`
|
`powershell -NoProfile -Command "Start-Process schtasks -Verb RunAs -ArgumentList '/create', '/tn', '${appName}', '/xml', '${taskFilePath}', '/f' -WindowStyle Hidden -Wait"`
|
||||||
)
|
)
|
||||||
|
// 验证任务是否创建成功
|
||||||
|
await new Promise((resolve) => setTimeout(resolve, 1000))
|
||||||
|
const created = await checkAutoRun()
|
||||||
|
taskCreated = created
|
||||||
|
if (!created) {
|
||||||
|
await managerLogger.warn('Scheduled task creation may have failed or been rejected')
|
||||||
|
}
|
||||||
} catch {
|
} catch {
|
||||||
await managerLogger.info('Maybe the user rejected the UAC dialog?')
|
await managerLogger.info('Scheduled task creation failed, trying registry fallback')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// 任务计划程序失败时使用注册表备用方案(适用于 Windows IoT LTSC 等受限环境)
|
||||||
|
if (!taskCreated) {
|
||||||
|
await managerLogger.info('Using registry fallback for auto-run')
|
||||||
|
try {
|
||||||
|
const regPath = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'
|
||||||
|
const regValue = `"${exePath()}"`
|
||||||
|
await execPromise(`reg add "${regPath}" /v "${appName}" /t REG_SZ /d ${regValue} /f`)
|
||||||
|
await managerLogger.info('Registry auto-run entry created successfully')
|
||||||
|
} catch (regError) {
|
||||||
|
await managerLogger.error('Failed to create registry auto-run entry:', regError)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -137,16 +177,26 @@ export async function disableAutoRun(): Promise<void> {
|
|||||||
const execPromise = promisify(exec)
|
const execPromise = promisify(exec)
|
||||||
const { checkAdminPrivileges } = await import('../core/manager')
|
const { checkAdminPrivileges } = await import('../core/manager')
|
||||||
const isAdmin = await checkAdminPrivileges()
|
const isAdmin = await checkAdminPrivileges()
|
||||||
|
|
||||||
|
// 删除任务计划程序中的任务
|
||||||
|
try {
|
||||||
if (isAdmin) {
|
if (isAdmin) {
|
||||||
await execPromise(`%SystemRoot%\\System32\\schtasks.exe /delete /tn "${appName}" /f`)
|
await execPromise(`%SystemRoot%\\System32\\schtasks.exe /delete /tn "${appName}" /f`)
|
||||||
} else {
|
} else {
|
||||||
try {
|
|
||||||
await execPromise(
|
await execPromise(
|
||||||
`powershell -NoProfile -Command "Start-Process schtasks -Verb RunAs -ArgumentList '/delete', '/tn', '${appName}', '/f' -WindowStyle Hidden"`
|
`powershell -NoProfile -Command "Start-Process schtasks -Verb RunAs -ArgumentList '/delete', '/tn', '${appName}', '/f' -WindowStyle Hidden -Wait"`
|
||||||
)
|
)
|
||||||
} catch {
|
|
||||||
await managerLogger.info('Maybe the user rejected the UAC dialog?')
|
|
||||||
}
|
}
|
||||||
|
} catch {
|
||||||
|
// 任务可能不存在,忽略错误
|
||||||
|
}
|
||||||
|
|
||||||
|
// 同时删除注册表备用方案
|
||||||
|
try {
|
||||||
|
const regPath = 'HKCU\\Software\\Microsoft\\Windows\\CurrentVersion\\Run'
|
||||||
|
await execPromise(`reg delete "${regPath}" /v "${appName}" /f`)
|
||||||
|
} catch {
|
||||||
|
// 注册表项可能不存在,忽略错误
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (process.platform === 'darwin') {
|
if (process.platform === 'darwin') {
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user