Refactor Windows installer update process for improved file handling
All checks were successful
farmcontrol/farmcontrol-ui/pipeline/head This commit looks good

- Introduced new macros `tryRenameProbe` and `waitForInstallDirWritable` to enhance the update process by ensuring files are accessible before replacement.
- Updated the `swapUpdateStaging` macro to include checks for file locks and implement a retry mechanism for directory removal, improving reliability during updates.
- Enhanced detail logging for better visibility during the update process.
This commit is contained in:
Tom Butcher 2026-08-08 22:35:37 +01:00
parent ddaeb3cfff
commit 29bf25cc20

View File

@ -121,8 +121,74 @@ Var FinalInstDir
${EndIf} ${EndIf}
!macroend !macroend
; Returns 0 in $R9 when $R8 can be renamed (file unlocked / path free).
; _ID must be unique per insert so labels do not collide.
!macro tryRenameProbe _ID
StrCpy $R9 1
${IfNot} ${FileExists} "$R8"
StrCpy $R9 0
Goto try_rename_probe_done_${_ID}
${EndIf}
ClearErrors
Rename "$R8" "$R8.updating"
${If} ${Errors}
Goto try_rename_probe_done_${_ID}
${EndIf}
; Leave the .updating name the whole tree is about to be deleted.
StrCpy $R9 0
try_rename_probe_done_${_ID}:
!macroend
; Wait until the live install directory is released by the quitting app.
!macro waitForInstallDirWritable
!insertmacro progressStatus "Waiting for Farm Control to release install files..."
DetailPrint "Waiting for install directory to become writable..."
StrCpy $R7 0
wait_install_writable:
; Probe the main binaries rename fails while the process still holds them.
StrCpy $R8 "$FinalInstDir\bin\FarmControl.exe"
!insertmacro tryRenameProbe farmcontrol
${If} $R9 != 0
Goto wait_install_writable_retry
${EndIf}
StrCpy $R8 "$FinalInstDir\bin\launcher.exe"
!insertmacro tryRenameProbe launcher
${If} $R9 != 0
Goto wait_install_writable_retry
${EndIf}
; Also probe creating a temp file in the install root.
ClearErrors
FileOpen $R8 "$FinalInstDir\.farmcontrol-write-probe" w
${If} $R8 == ""
Goto wait_install_writable_retry
${EndIf}
FileClose $R8
Delete "$FinalInstDir\.farmcontrol-write-probe"
Goto wait_install_writable_done
wait_install_writable_retry:
IntOp $R7 $R7 + 1
${If} $R7 < 60
Sleep 500
Goto wait_install_writable
${EndIf}
!insertmacro progressFailure "Could not access the previous Farm Control installation."
Abort
wait_install_writable_done:
!macroend
!macro swapUpdateStaging !macro swapUpdateStaging
!insertmacro progressPhase "Applying update" !insertmacro progressPhase "Applying update"
${If} ${FileExists} "$FinalInstDir"
!insertmacro waitForInstallDirWritable
!insertmacro progressStatus "Replacing Farm Control with the new version..." !insertmacro progressStatus "Replacing Farm Control with the new version..."
DetailPrint "Replacing Farm Control with staged update..." DetailPrint "Replacing Farm Control with staged update..."
@ -138,6 +204,10 @@ Var FinalInstDir
!insertmacro progressFailure "Could not remove the previous Farm Control installation." !insertmacro progressFailure "Could not remove the previous Farm Control installation."
Abort Abort
${EndIf} ${EndIf}
${EndIf}
!insertmacro progressStatus "Activating new Farm Control installation..."
DetailPrint "Activating staged update..."
ClearErrors ClearErrors
Rename "$INSTDIR" "$FinalInstDir" Rename "$INSTDIR" "$FinalInstDir"