mirror of
https://gh.catmak.name/https://github.com/mihomo-party-org/mihomo-party
synced 2025-12-27 05:00:30 +08:00
support change data dir
This commit is contained in:
parent
fe2f4fa2ad
commit
160537bd48
@ -2,7 +2,7 @@ import { controledMihomoConfigPath } from '../utils/dirs'
|
|||||||
import { readFile, writeFile } from 'fs/promises'
|
import { readFile, writeFile } from 'fs/promises'
|
||||||
import yaml from 'yaml'
|
import yaml from 'yaml'
|
||||||
import { getAxios, startMihomoMemory, startMihomoTraffic } from '../core/mihomoApi'
|
import { getAxios, startMihomoMemory, startMihomoTraffic } from '../core/mihomoApi'
|
||||||
import { generateProfile } from '../resolve/factory'
|
import { generateProfile } from '../core/factory'
|
||||||
import { getAppConfig } from './app'
|
import { getAppConfig } from './app'
|
||||||
import { defaultControledMihomoConfig } from '../utils/template'
|
import { defaultControledMihomoConfig } from '../utils/template'
|
||||||
|
|
||||||
|
|||||||
@ -8,6 +8,7 @@ import {
|
|||||||
import { mihomoWorkConfigPath } from '../utils/dirs'
|
import { mihomoWorkConfigPath } from '../utils/dirs'
|
||||||
import yaml from 'yaml'
|
import yaml from 'yaml'
|
||||||
import fs from 'fs'
|
import fs from 'fs'
|
||||||
|
import { readFile } from 'fs/promises'
|
||||||
|
|
||||||
export async function generateProfile(): Promise<void> {
|
export async function generateProfile(): Promise<void> {
|
||||||
const { current } = await getProfileConfig()
|
const { current } = await getProfileConfig()
|
||||||
@ -59,3 +60,11 @@ function runOverrideScript(profile: IMihomoConfig, script: string): IMihomoConfi
|
|||||||
return profile
|
return profile
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function getRuntimeConfigStr(): Promise<string> {
|
||||||
|
return await readFile(mihomoWorkConfigPath(), 'utf8')
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function getRuntimeConfig(): Promise<IMihomoConfig> {
|
||||||
|
return yaml.parse(await getRuntimeConfigStr())
|
||||||
|
}
|
||||||
@ -6,7 +6,7 @@ import {
|
|||||||
mihomoWorkConfigPath,
|
mihomoWorkConfigPath,
|
||||||
mihomoWorkDir
|
mihomoWorkDir
|
||||||
} from '../utils/dirs'
|
} from '../utils/dirs'
|
||||||
import { generateProfile } from '../resolve/factory'
|
import { generateProfile } from './factory'
|
||||||
import { getAppConfig, patchAppConfig } from '../config'
|
import { getAppConfig, patchAppConfig } from '../config'
|
||||||
import { dialog, safeStorage } from 'electron'
|
import { dialog, safeStorage } from 'electron'
|
||||||
import { pauseWebsockets } from './mihomoApi'
|
import { pauseWebsockets } from './mihomoApi'
|
||||||
|
|||||||
@ -2,7 +2,7 @@ import axios, { AxiosInstance } from 'axios'
|
|||||||
import { getAppConfig, getControledMihomoConfig } from '../config'
|
import { getAppConfig, getControledMihomoConfig } from '../config'
|
||||||
import { mainWindow } from '..'
|
import { mainWindow } from '..'
|
||||||
import WebSocket from 'ws'
|
import WebSocket from 'ws'
|
||||||
import { tray } from './tray'
|
import { tray } from '../resolve/tray'
|
||||||
import { calcTraffic } from '../utils/calc'
|
import { calcTraffic } from '../utils/calc'
|
||||||
|
|
||||||
let axiosIns: AxiosInstance = null!
|
let axiosIns: AxiosInstance = null!
|
||||||
|
|||||||
@ -2,14 +2,14 @@ import { electronApp, optimizer, is } from '@electron-toolkit/utils'
|
|||||||
import { registerIpcMainHandlers } from './utils/ipc'
|
import { registerIpcMainHandlers } from './utils/ipc'
|
||||||
import windowStateKeeper from 'electron-window-state'
|
import windowStateKeeper from 'electron-window-state'
|
||||||
import { app, shell, BrowserWindow, Menu, dialog, Notification } from 'electron'
|
import { app, shell, BrowserWindow, Menu, dialog, Notification } from 'electron'
|
||||||
import { stopCore } from './core/manager'
|
|
||||||
import { triggerSysProxy } from './resolve/sysproxy'
|
|
||||||
import icon from '../../resources/icon.png?asset'
|
|
||||||
import { createTray } from './core/tray'
|
|
||||||
import { init } from './resolve/init'
|
|
||||||
import { addProfileItem, getAppConfig } from './config'
|
|
||||||
import { join } from 'path'
|
|
||||||
import { startMihomoMemory, stopMihomoMemory } from './core/mihomoApi'
|
import { startMihomoMemory, stopMihomoMemory } from './core/mihomoApi'
|
||||||
|
import { addProfileItem, getAppConfig } from './config'
|
||||||
|
import { stopCore } from './core/manager'
|
||||||
|
import { triggerSysProxy } from './sys/sysproxy'
|
||||||
|
import icon from '../../resources/icon.png?asset'
|
||||||
|
import { createTray } from './resolve/tray'
|
||||||
|
import { init } from './utils/init'
|
||||||
|
import { join } from 'path'
|
||||||
|
|
||||||
export let mainWindow: BrowserWindow | null = null
|
export let mainWindow: BrowserWindow | null = null
|
||||||
export let destroyTimer: NodeJS.Timeout | null = null
|
export let destroyTimer: NodeJS.Timeout | null = null
|
||||||
|
|||||||
@ -7,11 +7,11 @@ import {
|
|||||||
import icoIcon from '../../../resources/icon.ico?asset'
|
import icoIcon from '../../../resources/icon.ico?asset'
|
||||||
import pngIcon from '../../../resources/icon.png?asset'
|
import pngIcon from '../../../resources/icon.png?asset'
|
||||||
import templateIcon from '../../../resources/iconTemplate.png?asset'
|
import templateIcon from '../../../resources/iconTemplate.png?asset'
|
||||||
import { patchMihomoConfig } from './mihomoApi'
|
import { patchMihomoConfig } from '../core/mihomoApi'
|
||||||
import { mainWindow, showMainWindow } from '..'
|
import { mainWindow, showMainWindow } from '..'
|
||||||
import { app, ipcMain, Menu, nativeImage, shell, Tray } from 'electron'
|
import { app, ipcMain, Menu, nativeImage, shell, Tray } from 'electron'
|
||||||
import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from '../utils/dirs'
|
import { dataDir, logDir, mihomoCoreDir, mihomoWorkDir } from '../utils/dirs'
|
||||||
import { triggerSysProxy } from '../resolve/sysproxy'
|
import { triggerSysProxy } from '../sys/sysproxy'
|
||||||
|
|
||||||
export let tray: Tray | null = null
|
export let tray: Tray | null = null
|
||||||
|
|
||||||
@ -105,7 +105,7 @@ const buildContextMenu = async (): Promise<Menu> => {
|
|||||||
{
|
{
|
||||||
type: 'normal',
|
type: 'normal',
|
||||||
label: '应用目录',
|
label: '应用目录',
|
||||||
click: (): Promise<string> => shell.openPath(dataDir)
|
click: (): Promise<string> => shell.openPath(dataDir())
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
type: 'normal',
|
type: 'normal',
|
||||||
@ -76,7 +76,7 @@ export async function checkAutoRun(): Promise<boolean> {
|
|||||||
export async function enableAutoRun(): Promise<void> {
|
export async function enableAutoRun(): Promise<void> {
|
||||||
if (process.platform === 'win32') {
|
if (process.platform === 'win32') {
|
||||||
const execPromise = promisify(exec)
|
const execPromise = promisify(exec)
|
||||||
const taskFilePath = path.join(dataDir, `${appName}.xml`)
|
const taskFilePath = path.join(dataDir(), `${appName}.xml`)
|
||||||
await writeFile(taskFilePath, taskXml)
|
await writeFile(taskFilePath, taskXml)
|
||||||
await execPromise(`schtasks /create /tn "${appName}" /xml "${taskFilePath}" /f`)
|
await execPromise(`schtasks /create /tn "${appName}" /xml "${taskFilePath}" /f`)
|
||||||
}
|
}
|
||||||
43
src/main/sys/misc.ts
Normal file
43
src/main/sys/misc.ts
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
import { exec, execFile } from 'child_process'
|
||||||
|
import { dialog } from 'electron'
|
||||||
|
import { readFile } from 'fs/promises'
|
||||||
|
import path from 'path'
|
||||||
|
import { promisify } from 'util'
|
||||||
|
import { exePath, mihomoCorePath, 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 async function openUWPTool(): Promise<void> {
|
||||||
|
const execFilePromise = promisify(execFile)
|
||||||
|
const uwpToolPath = path.join(resourcesDir(), 'files', 'enableLoopback.exe')
|
||||||
|
await execFilePromise(uwpToolPath)
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setupFirewall(): Promise<void> {
|
||||||
|
const execPromise = promisify(exec)
|
||||||
|
const removeCommand = `
|
||||||
|
Remove-NetFirewallRule -DisplayName "mihomo" -ErrorAction SilentlyContinue
|
||||||
|
Remove-NetFirewallRule -DisplayName "mihomo-alpha" -ErrorAction SilentlyContinue
|
||||||
|
Remove-NetFirewallRule -DisplayName "Mihomo Party" -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' })
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,6 +1,6 @@
|
|||||||
import { triggerAutoProxy, triggerManualProxy } from '@mihomo-party/sysproxy'
|
import { triggerAutoProxy, triggerManualProxy } from '@mihomo-party/sysproxy'
|
||||||
import { getAppConfig, getControledMihomoConfig } from '../config'
|
import { getAppConfig, getControledMihomoConfig } from '../config'
|
||||||
import { pacPort } from './server'
|
import { pacPort } from '../resolve/server'
|
||||||
|
|
||||||
let defaultBypass: string[]
|
let defaultBypass: string[]
|
||||||
|
|
||||||
@ -1,10 +1,37 @@
|
|||||||
import { is } from '@electron-toolkit/utils'
|
import { is } from '@electron-toolkit/utils'
|
||||||
import { app } from 'electron'
|
import { app } from 'electron'
|
||||||
|
import fs from 'fs'
|
||||||
|
import { rm, writeFile } from 'fs/promises'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
|
|
||||||
export const dataDir = app.getPath('userData')
|
|
||||||
export const homeDir = app.getPath('home')
|
export const homeDir = app.getPath('home')
|
||||||
|
|
||||||
|
export function isPortable(): boolean {
|
||||||
|
return fs.existsSync(path.join(exeDir(), 'PORTABLE'))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function setPortable(portable: boolean): Promise<void> {
|
||||||
|
if (portable) {
|
||||||
|
await writeFile(path.join(exeDir(), 'PORTABLE'), '')
|
||||||
|
} else {
|
||||||
|
await rm(path.join(exeDir(), 'PORTABLE'))
|
||||||
|
}
|
||||||
|
app.relaunch()
|
||||||
|
app.quit()
|
||||||
|
}
|
||||||
|
|
||||||
|
export function dataDir(): string {
|
||||||
|
if (isPortable()) {
|
||||||
|
return path.join(exeDir(), 'data')
|
||||||
|
} else {
|
||||||
|
return app.getPath('userData')
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function exeDir(): string {
|
||||||
|
return path.dirname(exePath())
|
||||||
|
}
|
||||||
|
|
||||||
export function exePath(): string {
|
export function exePath(): string {
|
||||||
return app.getPath('exe')
|
return app.getPath('exe')
|
||||||
}
|
}
|
||||||
@ -35,19 +62,19 @@ export function mihomoCorePath(core: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function appConfigPath(): string {
|
export function appConfigPath(): string {
|
||||||
return path.join(dataDir, 'config.yaml')
|
return path.join(dataDir(), 'config.yaml')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function controledMihomoConfigPath(): string {
|
export function controledMihomoConfigPath(): string {
|
||||||
return path.join(dataDir, 'mihomo.yaml')
|
return path.join(dataDir(), 'mihomo.yaml')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function profileConfigPath(): string {
|
export function profileConfigPath(): string {
|
||||||
return path.join(dataDir, 'profile.yaml')
|
return path.join(dataDir(), 'profile.yaml')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function profilesDir(): string {
|
export function profilesDir(): string {
|
||||||
return path.join(dataDir, 'profiles')
|
return path.join(dataDir(), 'profiles')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function profilePath(id: string): string {
|
export function profilePath(id: string): string {
|
||||||
@ -55,11 +82,11 @@ export function profilePath(id: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function overrideDir(): string {
|
export function overrideDir(): string {
|
||||||
return path.join(dataDir, 'override')
|
return path.join(dataDir(), 'override')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function overrideConfigPath(): string {
|
export function overrideConfigPath(): string {
|
||||||
return path.join(dataDir, 'override.yaml')
|
return path.join(dataDir(), 'override.yaml')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function overridePath(id: string): string {
|
export function overridePath(id: string): string {
|
||||||
@ -67,11 +94,11 @@ export function overridePath(id: string): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function mihomoWorkDir(): string {
|
export function mihomoWorkDir(): string {
|
||||||
return path.join(dataDir, 'work')
|
return path.join(dataDir(), 'work')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mihomoTestDir(): string {
|
export function mihomoTestDir(): string {
|
||||||
return path.join(dataDir, 'test')
|
return path.join(dataDir(), 'test')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function mihomoWorkConfigPath(): string {
|
export function mihomoWorkConfigPath(): string {
|
||||||
@ -79,7 +106,7 @@ export function mihomoWorkConfigPath(): string {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function logDir(): string {
|
export function logDir(): string {
|
||||||
return path.join(dataDir, 'logs')
|
return path.join(dataDir(), 'logs')
|
||||||
}
|
}
|
||||||
|
|
||||||
export function logPath(): string {
|
export function logPath(): string {
|
||||||
|
|||||||
@ -11,20 +11,20 @@ import {
|
|||||||
profilePath,
|
profilePath,
|
||||||
profilesDir,
|
profilesDir,
|
||||||
resourcesFilesDir
|
resourcesFilesDir
|
||||||
} from '../utils/dirs'
|
} from './dirs'
|
||||||
import {
|
import {
|
||||||
defaultConfig,
|
defaultConfig,
|
||||||
defaultControledMihomoConfig,
|
defaultControledMihomoConfig,
|
||||||
defaultOverrideConfig,
|
defaultOverrideConfig,
|
||||||
defaultProfile,
|
defaultProfile,
|
||||||
defaultProfileConfig
|
defaultProfileConfig
|
||||||
} from '../utils/template'
|
} from './template'
|
||||||
import yaml from 'yaml'
|
import yaml from 'yaml'
|
||||||
import { mkdir, writeFile, copyFile } from 'fs/promises'
|
import { mkdir, writeFile, copyFile } from 'fs/promises'
|
||||||
import { existsSync } from 'fs'
|
import { existsSync } from 'fs'
|
||||||
import path from 'path'
|
import path from 'path'
|
||||||
import { startPacServer } from './server'
|
import { startPacServer } from '../resolve/server'
|
||||||
import { triggerSysProxy } from './sysproxy'
|
import { triggerSysProxy } from '../sys/sysproxy'
|
||||||
import { getAppConfig } from '../config'
|
import { getAppConfig } from '../config'
|
||||||
import { app } from 'electron'
|
import { app } from 'electron'
|
||||||
import { startCore } from '../core/manager'
|
import { startCore } from '../core/manager'
|
||||||
@ -32,8 +32,8 @@ import { initProfileUpdater } from '../core/profileUpdater'
|
|||||||
import { startMihomoTraffic } from '../core/mihomoApi'
|
import { startMihomoTraffic } from '../core/mihomoApi'
|
||||||
|
|
||||||
async function initDirs(): Promise<void> {
|
async function initDirs(): Promise<void> {
|
||||||
if (!existsSync(dataDir)) {
|
if (!existsSync(dataDir())) {
|
||||||
await mkdir(dataDir)
|
await mkdir(dataDir())
|
||||||
}
|
}
|
||||||
if (!existsSync(profilesDir())) {
|
if (!existsSync(profilesDir())) {
|
||||||
await mkdir(profilesDir())
|
await mkdir(profilesDir())
|
||||||
@ -1,4 +1,4 @@
|
|||||||
import { app, dialog, ipcMain, safeStorage } from 'electron'
|
import { app, ipcMain, safeStorage } from 'electron'
|
||||||
import {
|
import {
|
||||||
mihomoChangeProxy,
|
mihomoChangeProxy,
|
||||||
mihomoCloseAllConnections,
|
mihomoCloseAllConnections,
|
||||||
@ -19,7 +19,7 @@ import {
|
|||||||
stopMihomoConnections,
|
stopMihomoConnections,
|
||||||
stopMihomoLogs
|
stopMihomoLogs
|
||||||
} from '../core/mihomoApi'
|
} from '../core/mihomoApi'
|
||||||
import { checkAutoRun, disableAutoRun, enableAutoRun } from '../resolve/autoRun'
|
import { checkAutoRun, disableAutoRun, enableAutoRun } from '../sys/autoRun'
|
||||||
import {
|
import {
|
||||||
getAppConfig,
|
getAppConfig,
|
||||||
patchAppConfig,
|
patchAppConfig,
|
||||||
@ -45,14 +45,11 @@ import {
|
|||||||
updateOverrideItem
|
updateOverrideItem
|
||||||
} from '../config'
|
} from '../config'
|
||||||
import { isEncryptionAvailable, manualGrantCorePermition, restartCore } from '../core/manager'
|
import { isEncryptionAvailable, manualGrantCorePermition, restartCore } from '../core/manager'
|
||||||
import { triggerSysProxy } from '../resolve/sysproxy'
|
import { triggerSysProxy } from '../sys/sysproxy'
|
||||||
import { checkUpdate } from '../resolve/autoUpdater'
|
import { checkUpdate } from '../resolve/autoUpdater'
|
||||||
import { exePath, mihomoCorePath, mihomoWorkConfigPath, resourcesDir } from './dirs'
|
import { getFilePath, openUWPTool, readTextFile, setupFirewall } from '../sys/misc'
|
||||||
import { exec, execFile } from 'child_process'
|
import { getRuntimeConfig, getRuntimeConfigStr } from '../core/factory'
|
||||||
import yaml from 'yaml'
|
import { isPortable, setPortable } from './dirs'
|
||||||
import path from 'path'
|
|
||||||
import { promisify } from 'util'
|
|
||||||
import { readFile } from 'fs/promises'
|
|
||||||
|
|
||||||
function ipcErrorWrapper<T>( // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
function ipcErrorWrapper<T>( // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
fn: (...args: any[]) => Promise<T> // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
fn: (...args: any[]) => Promise<T> // eslint-disable-next-line @typescript-eslint/no-explicit-any
|
||||||
@ -138,50 +135,7 @@ export function registerIpcMainHandlers(): void {
|
|||||||
ipcMain.handle('platform', () => process.platform)
|
ipcMain.handle('platform', () => process.platform)
|
||||||
ipcMain.handle('openUWPTool', ipcErrorWrapper(openUWPTool))
|
ipcMain.handle('openUWPTool', ipcErrorWrapper(openUWPTool))
|
||||||
ipcMain.handle('setupFirewall', ipcErrorWrapper(setupFirewall))
|
ipcMain.handle('setupFirewall', ipcErrorWrapper(setupFirewall))
|
||||||
|
ipcMain.handle('setPortable', (_e, portable) => ipcErrorWrapper(setPortable)(portable))
|
||||||
|
ipcMain.handle('isPortable', isPortable)
|
||||||
ipcMain.handle('quitApp', () => app.quit())
|
ipcMain.handle('quitApp', () => app.quit())
|
||||||
}
|
}
|
||||||
|
|
||||||
function getFilePath(ext: string[]): string[] | undefined {
|
|
||||||
return dialog.showOpenDialogSync({
|
|
||||||
title: '选择订阅文件',
|
|
||||||
filters: [{ name: `${ext} file`, extensions: ext }],
|
|
||||||
properties: ['openFile']
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
async function readTextFile(filePath: string): Promise<string> {
|
|
||||||
return await readFile(filePath, 'utf8')
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getRuntimeConfigStr(): Promise<string> {
|
|
||||||
return readFile(mihomoWorkConfigPath(), 'utf8')
|
|
||||||
}
|
|
||||||
|
|
||||||
async function getRuntimeConfig(): Promise<IMihomoConfig> {
|
|
||||||
return yaml.parse(await getRuntimeConfigStr())
|
|
||||||
}
|
|
||||||
|
|
||||||
async function openUWPTool(): Promise<void> {
|
|
||||||
const execFilePromise = promisify(execFile)
|
|
||||||
const uwpToolPath = path.join(resourcesDir(), 'files', 'enableLoopback.exe')
|
|
||||||
await execFilePromise(uwpToolPath)
|
|
||||||
}
|
|
||||||
|
|
||||||
async function setupFirewall(): Promise<void> {
|
|
||||||
const execPromise = promisify(exec)
|
|
||||||
const removeCommand = `
|
|
||||||
Remove-NetFirewallRule -DisplayName "mihomo" -ErrorAction SilentlyContinue
|
|
||||||
Remove-NetFirewallRule -DisplayName "mihomo-alpha" -ErrorAction SilentlyContinue
|
|
||||||
Remove-NetFirewallRule -DisplayName "Mihomo Party" -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' })
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@ -1,4 +1,4 @@
|
|||||||
import { Button, Input, Switch, Tab, Tabs } from '@nextui-org/react'
|
import { Button, Input, Select, SelectItem, Switch, Tab, Tabs } from '@nextui-org/react'
|
||||||
import BasePage from '@renderer/components/base/base-page'
|
import BasePage from '@renderer/components/base/base-page'
|
||||||
import SettingCard from '@renderer/components/base/base-setting-card'
|
import SettingCard from '@renderer/components/base/base-setting-card'
|
||||||
import SettingItem from '@renderer/components/base/base-setting-item'
|
import SettingItem from '@renderer/components/base/base-setting-item'
|
||||||
@ -9,7 +9,9 @@ import {
|
|||||||
disableAutoRun,
|
disableAutoRun,
|
||||||
quitApp,
|
quitApp,
|
||||||
checkUpdate,
|
checkUpdate,
|
||||||
patchControledMihomoConfig
|
patchControledMihomoConfig,
|
||||||
|
isPortable,
|
||||||
|
setPortable
|
||||||
} from '@renderer/utils/ipc'
|
} from '@renderer/utils/ipc'
|
||||||
import { IoLogoGithub } from 'react-icons/io5'
|
import { IoLogoGithub } from 'react-icons/io5'
|
||||||
import { platform, version } from '@renderer/utils/init'
|
import { platform, version } from '@renderer/utils/init'
|
||||||
@ -20,10 +22,8 @@ import { useTheme } from 'next-themes'
|
|||||||
|
|
||||||
const Settings: React.FC = () => {
|
const Settings: React.FC = () => {
|
||||||
const { setTheme } = useTheme()
|
const { setTheme } = useTheme()
|
||||||
const { data: enable, mutate } = useSWR('checkAutoRun', checkAutoRun, {
|
const { data: enable, mutate: mutateEnable } = useSWR('checkAutoRun', checkAutoRun)
|
||||||
errorRetryCount: 5,
|
const { data: portable, mutate: mutatePortable } = useSWR('isPortable', isPortable)
|
||||||
errorRetryInterval: 200
|
|
||||||
})
|
|
||||||
const { appConfig, patchAppConfig } = useAppConfig()
|
const { appConfig, patchAppConfig } = useAppConfig()
|
||||||
const {
|
const {
|
||||||
silentStart = false,
|
silentStart = false,
|
||||||
@ -100,7 +100,7 @@ const Settings: React.FC = () => {
|
|||||||
} catch (e) {
|
} catch (e) {
|
||||||
alert(e)
|
alert(e)
|
||||||
} finally {
|
} finally {
|
||||||
mutate()
|
mutateEnable()
|
||||||
}
|
}
|
||||||
}}
|
}}
|
||||||
/>
|
/>
|
||||||
@ -134,6 +134,27 @@ const Settings: React.FC = () => {
|
|||||||
/>
|
/>
|
||||||
</SettingItem>
|
</SettingItem>
|
||||||
)}
|
)}
|
||||||
|
{platform === 'win32' && (
|
||||||
|
<SettingItem title="数据存储路径" divider>
|
||||||
|
<Select
|
||||||
|
className="w-[150px]"
|
||||||
|
size="sm"
|
||||||
|
selectedKeys={new Set([portable ? 'portable' : 'data'])}
|
||||||
|
onSelectionChange={async (v) => {
|
||||||
|
try {
|
||||||
|
await setPortable(v.currentKey === 'portable')
|
||||||
|
} catch (e) {
|
||||||
|
alert(e)
|
||||||
|
} finally {
|
||||||
|
mutatePortable()
|
||||||
|
}
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<SelectItem key="data">AppData</SelectItem>
|
||||||
|
<SelectItem key="portable">安装目录</SelectItem>
|
||||||
|
</Select>
|
||||||
|
</SettingItem>
|
||||||
|
)}
|
||||||
|
|
||||||
<SettingItem title="背景色" divider={appTheme !== 'system'}>
|
<SettingItem title="背景色" divider={appTheme !== 'system'}>
|
||||||
<Tabs
|
<Tabs
|
||||||
|
|||||||
@ -245,6 +245,14 @@ export async function setupFirewall(): Promise<void> {
|
|||||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setupFirewall'))
|
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setupFirewall'))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function setPortable(portable: boolean): Promise<void> {
|
||||||
|
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('setPortable', portable))
|
||||||
|
}
|
||||||
|
|
||||||
|
export async function isPortable(): Promise<boolean> {
|
||||||
|
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('isPortable'))
|
||||||
|
}
|
||||||
|
|
||||||
export async function quitApp(): Promise<void> {
|
export async function quitApp(): Promise<void> {
|
||||||
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('quitApp'))
|
return ipcErrorWrapper(await window.electron.ipcRenderer.invoke('quitApp'))
|
||||||
}
|
}
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user