import { exePath, homeDir } from '../utils/dirs' import { tmpdir } from 'os' import { mkdir, readFile, rm, writeFile } from 'fs/promises' import { exec } from 'child_process' import { existsSync } from 'fs' import { promisify } from 'util' import path from 'path' import { managerLogger } from '../utils/logger' const appName = 'mihomo-party' function getTaskXml(asAdmin: boolean): string { const runLevel = asAdmin ? 'HighestAvailable' : 'LeastPrivilege' return ` true PT3S InteractiveToken ${runLevel} Parallel false false false false false false false true true false false false PT0S 3 "${exePath()}" ` } export async function checkAutoRun(): Promise { if (process.platform === 'win32') { const execPromise = promisify(exec) try { const { stdout } = await execPromise( `chcp 437 && %SystemRoot%\\System32\\schtasks.exe /query /tn "${appName}"` ) return stdout.includes(appName) } catch (e) { return false } } if (process.platform === 'darwin') { const execPromise = promisify(exec) const { stdout } = await execPromise( `osascript -e 'tell application "System Events" to get the name of every login item'` ) return stdout.includes(exePath().split('.app')[0].replace('/Applications/', '')) } if (process.platform === 'linux') { return existsSync(path.join(homeDir, '.config', 'autostart', `${appName}.desktop`)) } return false } export async function enableAutoRun(): Promise { if (process.platform === 'win32') { const execPromise = promisify(exec) const taskFilePath = path.join(tmpdir(), `${appName}.xml`) const { checkAdminPrivileges } = await import('../core/manager') const isAdmin = await checkAdminPrivileges() await writeFile(taskFilePath, Buffer.from(`\ufeff${getTaskXml(isAdmin)}`, 'utf-16le')) if (isAdmin) { await execPromise(`%SystemRoot%\\System32\\schtasks.exe /create /tn "${appName}" /xml "${taskFilePath}" /f`) } else { try { await execPromise( `powershell -Command "Start-Process schtasks -Verb RunAs -ArgumentList '/create', '/tn', '${appName}', '/xml', '${taskFilePath}', '/f' -WindowStyle Hidden"` ) } catch (e) { await managerLogger.info('Maybe the user rejected the UAC dialog?') } } } if (process.platform === 'darwin') { const execPromise = promisify(exec) await execPromise( `osascript -e 'tell application "System Events" to make login item at end with properties {path:"${exePath().split('.app')[0]}.app", hidden:false}'` ) } if (process.platform === 'linux') { let desktop = ` [Desktop Entry] Name=mihomo-party Exec=${exePath()} %U Terminal=false Type=Application Icon=mihomo-party StartupWMClass=mihomo-party Comment=Clash Party Categories=Utility; ` if (existsSync(`/usr/share/applications/${appName}.desktop`)) { desktop = await readFile(`/usr/share/applications/${appName}.desktop`, 'utf8') } const autostartDir = path.join(homeDir, '.config', 'autostart') if (!existsSync(autostartDir)) { await mkdir(autostartDir, { recursive: true }) } const desktopFilePath = path.join(autostartDir, `${appName}.desktop`) await writeFile(desktopFilePath, desktop) } } export async function disableAutoRun(): Promise { if (process.platform === 'win32') { const execPromise = promisify(exec) const { checkAdminPrivileges } = await import('../core/manager') const isAdmin = await checkAdminPrivileges() if (isAdmin) { await execPromise(`%SystemRoot%\\System32\\schtasks.exe /delete /tn "${appName}" /f`) } else { try { await execPromise(`powershell -Command "Start-Process schtasks -Verb RunAs -ArgumentList '/delete', '/tn', '${appName}', '/f' -WindowStyle Hidden"`) } catch (e) { await managerLogger.info('Maybe the user rejected the UAC dialog?') } } } if (process.platform === 'darwin') { const execPromise = promisify(exec) await execPromise( `osascript -e 'tell application "System Events" to delete login item "${exePath().split('.app')[0].replace('/Applications/', '')}"'` ) } if (process.platform === 'linux') { const desktopFilePath = path.join(homeDir, '.config', 'autostart', `${appName}.desktop`) await rm(desktopFilePath) } }