Enhance Windows installer with parent process ID handling for improved update reliability
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good
- Introduced a new variable to capture the parent process ID, allowing the installer to wait for the exact updater process instead of relying on executable names. - Updated the `restartFarmControlAfterUpdate` function to handle the new parent PID, ensuring a more reliable shutdown of the Farm Control application during updates. - Modified the `launchWindowsInstaller` function to pass the current process ID as an argument, enhancing the installer’s ability to manage application restarts effectively.
This commit is contained in:
parent
2bbecb0d6a
commit
28295f5912
@ -6,6 +6,7 @@ Var ProgressLogFile
|
||||
Var IsInAppUpdate
|
||||
Var RestartAfterInstall
|
||||
Var FinalInstDir
|
||||
Var UpdateParentPid
|
||||
|
||||
; Generate an include at compile time that defines APP_COPY_TOTAL_BYTES and
|
||||
; copyApplicationFilesWithProgress. The generated macro contains one File
|
||||
@ -23,6 +24,7 @@ Var FinalInstDir
|
||||
StrCpy $IsInAppUpdate "0"
|
||||
StrCpy $RestartAfterInstall "0"
|
||||
StrCpy $FinalInstDir ""
|
||||
StrCpy $UpdateParentPid "0"
|
||||
|
||||
${GetParameters} $R9
|
||||
|
||||
@ -38,6 +40,13 @@ Var FinalInstDir
|
||||
StrCpy $RestartAfterInstall "1"
|
||||
${EndIf}
|
||||
|
||||
ClearErrors
|
||||
${GetOptions} $R9 "/PARENTPID=" $R8
|
||||
${IfNot} ${Errors}
|
||||
; Convert to an integer before it is used in Win32 calls or taskkill.
|
||||
IntOp $UpdateParentPid $R8 + 0
|
||||
${EndIf}
|
||||
|
||||
; Prefer env var so paths with spaces are reliable; /LOG= remains supported.
|
||||
ReadEnvStr $ProgressLogFile "FARMCONTROL_INSTALL_LOG"
|
||||
${If} $ProgressLogFile == ""
|
||||
@ -330,22 +339,49 @@ Function restartFarmControlAfterUpdate
|
||||
!insertmacro progressSuccess
|
||||
|
||||
!insertmacro progressStatus "Waiting for Farm Control to close..."
|
||||
Sleep 2000
|
||||
|
||||
restart_wait_loop:
|
||||
ExecWait 'cmd.exe /c tasklist /FI "IMAGENAME eq FarmControl.exe" 2>nul | find /I "FarmControl.exe"' $R0
|
||||
${If} $R0 == 0
|
||||
Sleep 1500
|
||||
Goto restart_wait_loop
|
||||
${EndIf}
|
||||
ExecWait 'cmd.exe /c tasklist /FI "IMAGENAME eq launcher.exe" 2>nul | find /I "launcher.exe"' $R0
|
||||
${If} $R0 == 0
|
||||
Sleep 1500
|
||||
Goto restart_wait_loop
|
||||
${If} $UpdateParentPid > 0
|
||||
; Wait for the exact updater process rather than an executable name. CEF
|
||||
; 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 minutes for a graceful CEF shutdown.
|
||||
System::Call 'kernel32::WaitForSingleObject(p r0, i 120000) i .r1'
|
||||
System::Call 'kernel32::CloseHandle(p r0)'
|
||||
|
||||
${If} $1 == 258
|
||||
!insertmacro progressStatus "Farm Control is taking too long to close; forcing shutdown..."
|
||||
DetailPrint "Farm Control process $UpdateParentPid did not exit; terminating its process tree..."
|
||||
ExecWait 'taskkill /F /T /PID $UpdateParentPid' $R0
|
||||
${EndIf}
|
||||
${EndIf}
|
||||
${Else}
|
||||
; Compatibility fallback for manually launched older installers.
|
||||
StrCpy $R7 0
|
||||
restart_wait_loop:
|
||||
ExecWait 'cmd.exe /c tasklist /FI "IMAGENAME eq FarmControl.exe" 2>nul | find /I "FarmControl.exe"' $R0
|
||||
${If} $R0 != 0
|
||||
ExecWait 'cmd.exe /c tasklist /FI "IMAGENAME eq launcher.exe" 2>nul | find /I "launcher.exe"' $R0
|
||||
${EndIf}
|
||||
${If} $R0 != 0
|
||||
Goto restart_wait_done
|
||||
${EndIf}
|
||||
|
||||
IntOp $R7 $R7 + 1
|
||||
${If} $R7 < 80
|
||||
Sleep 1500
|
||||
Goto restart_wait_loop
|
||||
${EndIf}
|
||||
|
||||
!insertmacro progressStatus "Farm Control is taking too long to close; forcing shutdown..."
|
||||
!insertmacro quitFarmControl
|
||||
${EndIf}
|
||||
|
||||
restart_wait_done:
|
||||
; Give CEF descendants a moment to release DLLs before renaming the tree.
|
||||
Sleep 3000
|
||||
|
||||
${If} $IsInAppUpdate == "1"
|
||||
Sleep 1000
|
||||
!insertmacro swapUpdateStaging
|
||||
${EndIf}
|
||||
|
||||
|
||||
@ -262,9 +262,16 @@ export const launchWindowsInstaller = async (
|
||||
// /S = silent (https://nsis.sourceforge.io/Reference/SilentInstall)
|
||||
// /UPDATE = in-app update (stage into Farm Control.new; swap after exit)
|
||||
// /RESTARTFC = installer waits for this process to exit, swaps folders, relaunches
|
||||
// /PARENTPID = exact process to wait for (CEF may outlive the launcher)
|
||||
// /LOG= + FARMCONTROL_INSTALL_LOG = progress log
|
||||
// (installer:% / PHASE / STATUS / COPY_TOTAL / COPY_FILE)
|
||||
const installerArgs = ['/S', '/UPDATE', '/RESTARTFC', `/LOG=${logPath}`]
|
||||
const installerArgs = [
|
||||
'/S',
|
||||
'/UPDATE',
|
||||
'/RESTARTFC',
|
||||
`/PARENTPID=${process.pid}`,
|
||||
`/LOG=${logPath}`
|
||||
]
|
||||
|
||||
const installerProcess = spawn(resolvedPath, installerArgs, {
|
||||
detached: true,
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user