Memory 6542be8490
chore: ensure ESLint passes and format code & update changelog.md
* chore: ensure ESLint passes and format code

* chore: update changelog.md
2025-12-13 15:22:32 +08:00

109 lines
3.3 KiB
TypeScript

import { exec, execFile, spawn } from 'child_process'
import { app, dialog, nativeTheme, shell } from 'electron'
import { readFile } from 'fs/promises'
import path from 'path'
import { promisify } from 'util'
import {
dataDir,
exePath,
mihomoCorePath,
overridePath,
profilePath,
resourcesDir
} from '../utils/dirs'
export function getFilePath(ext: string[]): string[] | undefined {
return dialog.showOpenDialogSync({
title: '选择订阅文件',
filters: [{ name: `${ext} file`, extensions: ext }],
properties: ['openFile']
})
}
export async function readTextFile(filePath: string): Promise<string> {
return await readFile(filePath, 'utf8')
}
export function openFile(type: 'profile' | 'override', id: string, ext?: 'yaml' | 'js'): void {
if (type === 'profile') {
shell.openPath(profilePath(id))
}
if (type === 'override') {
shell.openPath(overridePath(id, ext || 'js'))
}
}
export async function openUWPTool(): Promise<void> {
const execPromise = promisify(exec)
const execFilePromise = promisify(execFile)
const uwpToolPath = path.join(resourcesDir(), 'files', 'enableLoopback.exe')
const { checkAdminPrivileges } = await import('../core/manager')
const isAdmin = await checkAdminPrivileges()
if (!isAdmin) {
const escapedPath = uwpToolPath.replace(/'/g, "''")
const command = `powershell -NoProfile -Command "Start-Process -FilePath '${escapedPath}' -Verb RunAs -Wait"`
await execPromise(command, { windowsHide: true })
return
}
await execFilePromise(uwpToolPath)
}
export async function setupFirewall(): Promise<void> {
const execPromise = promisify(exec)
const removeCommand = `
$rules = @("mihomo", "mihomo-alpha", "Mihomo Party")
foreach ($rule in $rules) {
if (Get-NetFirewallRule -DisplayName $rule -ErrorAction SilentlyContinue) {
Remove-NetFirewallRule -DisplayName $rule -ErrorAction SilentlyContinue
}
}
`
const createCommand = `
New-NetFirewallRule -DisplayName "mihomo" -Direction Inbound -Action Allow -Program "${mihomoCorePath('mihomo')}" -Enabled True -Profile Any -ErrorAction SilentlyContinue
New-NetFirewallRule -DisplayName "mihomo-alpha" -Direction Inbound -Action Allow -Program "${mihomoCorePath('mihomo-alpha')}" -Enabled True -Profile Any -ErrorAction SilentlyContinue
New-NetFirewallRule -DisplayName "Mihomo Party" -Direction Inbound -Action Allow -Program "${exePath()}" -Enabled True -Profile Any -ErrorAction SilentlyContinue
`
if (process.platform === 'win32') {
await execPromise(removeCommand, { shell: 'powershell' })
await execPromise(createCommand, { shell: 'powershell' })
}
}
export function setNativeTheme(theme: 'system' | 'light' | 'dark'): void {
nativeTheme.themeSource = theme
}
export function resetAppConfig(): void {
if (process.platform === 'win32') {
spawn(
'cmd',
[
'/C',
`"timeout /t 2 /nobreak >nul && rmdir /s /q "${dataDir()}" && start "" "${exePath()}""`
],
{
shell: true,
detached: true
}
).unref()
} else {
const script = `while kill -0 ${process.pid} 2>/dev/null; do
sleep 0.1
done
rm -rf '${dataDir()}'
${process.argv.join(' ')} & disown
exit
`
spawn('sh', ['-c', `"${script}"`], {
shell: true,
detached: true,
stdio: 'ignore'
})
}
app.quit()
}