fix: add -WindowStyle Hidden to powershell command to prevent window flash on Windows (#285)

This commit is contained in:
paisley
2026-03-04 14:51:44 +08:00
committed by GitHub
Unverified
parent 30b03add1c
commit 9703f361f9
2 changed files with 74 additions and 3 deletions

View File

@@ -722,8 +722,10 @@ export class GatewayManager extends EventEmitter {
try {
// Platform-specific command to find processes listening on the gateway port.
// On Windows, lsof doesn't exist; use PowerShell's Get-NetTCPConnection instead.
// -WindowStyle Hidden is used to prevent PowerShell from popping up a brief console window
// even when windowsHide: true is passed to cp.exec.
const cmd = process.platform === 'win32'
? `powershell -NoProfile -Command "(Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue).OwningProcess"`
? `powershell -WindowStyle Hidden -NoProfile -Command "(Get-NetTCPConnection -LocalPort ${port} -State Listen -ErrorAction SilentlyContinue).OwningProcess"`
: `lsof -i :${port} -sTCP:LISTEN -t`;
const { stdout } = await new Promise<{ stdout: string }>((resolve, reject) => {
@@ -754,10 +756,12 @@ export class GatewayManager extends EventEmitter {
for (const pid of pids) {
try {
if (process.platform === 'win32') {
// On Windows, use taskkill for reliable process group termination
// Use PowerShell with -WindowStyle Hidden to kill the process without
// flashing a black console window. taskkill.exe is a console app and
// can flash a window even when windowsHide: true is set.
import('child_process').then(cp => {
cp.exec(
`taskkill /PID ${pid} /T /F`,
`powershell -WindowStyle Hidden -NoProfile -Command "Stop-Process -Id ${pid} -Force -ErrorAction SilentlyContinue"`,
{ timeout: 5000, windowsHide: true },
() => { }
);

View File

@@ -3,6 +3,73 @@
; Install: enables long paths, adds resources\cli to user PATH for openclaw CLI.
; Uninstall: removes the PATH entry and optionally deletes user data.
!macro customCheckAppRunning
${GetProcessInfo} 0 $pid $1 $2 $3 $4
${if} $3 != "${APP_EXECUTABLE_FILENAME}"
${if} ${isUpdated}
# allow app to exit without explicit kill
Sleep 300
${endIf}
# Instead of launching cmd.exe /c tasklist, use the nsProcess plugin directly for all environments.
# This prevents the brief black cmd window from flashing.
${nsProcess::FindProcess} "${APP_EXECUTABLE_FILENAME}" $R0
${if} $R0 == 0
${if} ${isUpdated}
# allow app to exit without explicit kill
Sleep 1000
Goto doStopProcess
${endIf}
MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(appRunning)" /SD IDOK IDOK doStopProcess
Quit
doStopProcess:
DetailPrint `Closing running "${PRODUCT_NAME}"...`
# Silently kill the process using nsProcess instead of taskkill / cmd.exe
${nsProcess::KillProcess} "${APP_EXECUTABLE_FILENAME}" $R0
# to ensure that files are not "in-use"
Sleep 300
# Retry counter
StrCpy $R1 0
loop:
IntOp $R1 $R1 + 1
${nsProcess::FindProcess} "${APP_EXECUTABLE_FILENAME}" $R0
${if} $R0 == 0
# wait to give a chance to exit gracefully
Sleep 1000
${nsProcess::KillProcess} "${APP_EXECUTABLE_FILENAME}" $R0
${nsProcess::FindProcess} "${APP_EXECUTABLE_FILENAME}" $R0
${If} $R0 == 0
DetailPrint `Waiting for "${PRODUCT_NAME}" to close.`
Sleep 2000
${else}
Goto not_running
${endIf}
${else}
Goto not_running
${endIf}
# App likely running with elevated permissions.
# Ask user to close it manually
${if} $R1 > 1
MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY loop
Quit
${else}
Goto loop
${endIf}
not_running:
nsProcess::Unload
${endIf}
${endIf}
!macroend
!macro customInstall
; Enable Windows long path support (Windows 10 1607+ / Windows 11).
; pnpm virtual store paths can exceed the default MAX_PATH limit of 260 chars.