From bb2b8148c79e4e8d97b38329f540f9a4ce2c7607 Mon Sep 17 00:00:00 2001 From: Tom Butcher Date: Sun, 9 Aug 2026 11:37:14 +0100 Subject: [PATCH] Refine Windows installer shutdown process for improved reliability - Updated the `restartFarmControlAfterUpdate` function to terminate the Farm Control process directly, avoiding potential issues with tree kills that could affect the installer itself. - Added a PowerShell command to clean up any lingering CEF helper processes after the main process exits, ensuring a smoother update experience without blocking file renames. --- packaging/windows/installer.nsh | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/packaging/windows/installer.nsh b/packaging/windows/installer.nsh index 103b72d..57d5d10 100644 --- a/packaging/windows/installer.nsh +++ b/packaging/windows/installer.nsh @@ -345,12 +345,15 @@ Function restartFarmControlAfterUpdate ; builds can keep bun/renderer processes alive after the launcher exits. System::Call 'kernel32::OpenProcess(i 0x00100000, i 0, i $UpdateParentPid) p .r0' ${If} $0 != 0 - ; Allow two seconds for a graceful exit, then terminate the process tree. + ; Allow two seconds for a graceful exit, then terminate the process. System::Call 'kernel32::WaitForSingleObject(p r0, i 2000) i .r1' ${If} $1 == 258 !insertmacro progressStatus "Stopping Farm Control..." - DetailPrint "Farm Control process $UpdateParentPid did not exit; terminating its process tree..." - ExecWait 'taskkill /F /T /PID $UpdateParentPid' $R0 + DetailPrint "Farm Control process $UpdateParentPid did not exit; terminating it..." + ; Never use taskkill /T here: this installer is a direct child of the + ; updater process, so a tree kill would terminate the installer itself + ; before the folder swap (CEF builds hung at "Stopping Farm Control..."). + ExecWait 'taskkill /F /PID $UpdateParentPid' $R0 ; Verify that taskkill actually terminated the process before swapping. System::Call 'kernel32::WaitForSingleObject(p r0, i 10000) i .r1' @@ -389,6 +392,13 @@ Function restartFarmControlAfterUpdate ${EndIf} restart_wait_done: + ; CEF helper processes normally exit on their own once the main process is + ; gone, but sweep up any stragglers still running from the install + ; directory so the rename cannot be blocked. Matching on executable path + ; (not a tree kill) guarantees this installer, which runs from the Updates + ; folder, is never terminated. + ExecWait `powershell.exe -NoLogo -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "Get-CimInstance Win32_Process | Where-Object { $$_.ExecutablePath -like '$FinalInstDir\*' } | ForEach-Object { Stop-Process -Id $$_.ProcessId -Force -ErrorAction SilentlyContinue }"` $R0 + ; Give CEF descendants a moment to release DLLs before renaming the tree. Sleep 3000