fix: keep self-update on the active install path (#123)

This commit is contained in:
Zhicheng Han
2026-04-22 04:33:38 +02:00
committed by GitHub
parent 42a5e4052a
commit ffd825afe2
3 changed files with 250 additions and 18 deletions
+59 -9
View File
@@ -1,19 +1,69 @@
import { spawn } from 'child_process'
import { execFileSync, spawn } from 'child_process'
import { dirname, join } from 'path'
function getNodeBinDir() {
return dirname(process.execPath)
}
function getNpmBin() {
return join(getNodeBinDir(), process.platform === 'win32' ? 'npm.cmd' : 'npm')
}
function getCliBin() {
return join(getNodeBinDir(), process.platform === 'win32' ? 'hermes-web-ui.cmd' : 'hermes-web-ui')
}
function getWindowsShell() {
return process.env.ComSpec || 'cmd.exe'
}
function quoteForWindowsCommand(value: string) {
return `"${value.replace(/"/g, '""')}"`
}
function runUpdateInstall() {
if (process.platform === 'win32') {
return execFileSync(getWindowsShell(), ['/d', '/s', '/c', `${quoteForWindowsCommand(getNpmBin())} install -g hermes-web-ui@latest`], {
encoding: 'utf-8',
timeout: 120000,
stdio: ['pipe', 'pipe', 'pipe'],
windowsHide: true,
})
}
return execFileSync(getNpmBin(), ['install', '-g', 'hermes-web-ui@latest'], {
encoding: 'utf-8',
timeout: 120000,
stdio: ['pipe', 'pipe', 'pipe'],
})
}
function spawnRestart(port: string) {
if (process.platform === 'win32') {
return spawn(getWindowsShell(), ['/d', '/s', '/c', `${quoteForWindowsCommand(getCliBin())} restart --port ${port}`], {
detached: true,
stdio: 'ignore',
windowsHide: true,
})
}
return spawn(getCliBin(), ['restart', '--port', port], {
detached: true,
stdio: 'ignore',
windowsHide: true,
})
}
export async function handleUpdate(ctx: any) {
const isWin = process.platform === 'win32'
const cmd = isWin ? 'cmd /c npm install -g hermes-web-ui@latest' : 'npm install -g hermes-web-ui@latest'
try {
const { execSync } = await import('child_process')
const output = execSync(cmd, { encoding: 'utf-8', timeout: 120000, stdio: ['pipe', 'pipe', 'pipe'] })
const output = runUpdateInstall()
ctx.body = { success: true, message: output.trim() }
setTimeout(() => {
spawn(isWin ? 'cmd' : 'sh', isWin ? ['/c', 'hermes-web-ui restart'] : ['-c', 'hermes-web-ui restart'], {
detached: true, stdio: 'ignore', windowsHide: true,
}).unref()
spawnRestart(process.env.PORT || '8648').unref()
process.exit(0)
}, 2000)
} catch (err: any) {
ctx.status = 500; ctx.body = { success: false, message: err.stderr || err.message }
ctx.status = 500
ctx.body = { success: false, message: err.stderr || err.message }
}
}