From 4648c8ccc76f7481922482ed7ac325697a245ba4 Mon Sep 17 00:00:00 2001 From: Lotus CI Date: Wed, 23 Sep 2026 19:39:00 -0400 Subject: [PATCH] fix(updater): installer waits for the old cinny.exe to release (#1) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The updater launches the NSIS installer with /UPDATE and then exits the app, but a WebView2 app takes a moment to die and the template only sleeps 500 ms after its own kill before copying — so the copy raced the old process ("Error opening file for writing: cinny.exe"), and Ignore left the old exe in place. A NSIS_HOOK_PREINSTALL now, on /UPDATE only, polls until cinny.exe can really be opened for writing (every 250 ms, up to 15 s), then lets the template carry on. Checked under Wine with a real running exe: without the hook the copy fails; with it the installer waits out the remaining ~2.8 s and copies; a manual install (no /UPDATE) doesn't wait; a stuck process hits the 15 s cap and falls through to the template's own running-app handling. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_01PPmy3tPq869XDW4njjVaKA --- src-tauri/nsis/hooks.nsh | 35 +++++++++++++++++++++++++++++++++++ src-tauri/tauri.conf.json | 3 ++- 2 files changed, 37 insertions(+), 1 deletion(-) create mode 100644 src-tauri/nsis/hooks.nsh diff --git a/src-tauri/nsis/hooks.nsh b/src-tauri/nsis/hooks.nsh new file mode 100644 index 0000000..a581e08 --- /dev/null +++ b/src-tauri/nsis/hooks.nsh @@ -0,0 +1,35 @@ +; Lotus Chat NSIS installer hooks (tauri.conf.json → bundle.windows.nsis.installerHooks). + +; cinny-desktop #1 — auto-update hit "Error opening file for writing: cinny.exe". +; The updater launches this installer with /UPDATE and then exits the running +; app, but a WebView2 app takes a moment to die; the template only sleeps 500 ms +; after its own kill before copying files, so the copy raced the old process and +; Ignore left the old exe in place. On an update, wait until the exe can really +; be opened for writing (up to 15 s), then let the template carry on as usual. +!macro NSIS_HOOK_PREINSTALL + Push $R7 + Push $R8 + Push $R9 + ClearErrors + ${GetOptions} $CMDLINE "/UPDATE" $R7 + IfErrors lotus_exe_ready + IfFileExists "$INSTDIR\${MAINBINARYNAME}.exe" 0 lotus_exe_ready + StrCpy $R9 0 + lotus_exe_probe: + ClearErrors + FileOpen $R8 "$INSTDIR\${MAINBINARYNAME}.exe" a + IfErrors lotus_exe_locked + FileClose $R8 + Goto lotus_exe_ready + lotus_exe_locked: + IntOp $R9 $R9 + 1 + ; 60 × 250 ms = 15 s; past that fall through to the template's own + ; running-app handling rather than hang the update. + IntCmp $R9 60 lotus_exe_ready 0 lotus_exe_ready + Sleep 250 + Goto lotus_exe_probe + lotus_exe_ready: + Pop $R9 + Pop $R8 + Pop $R7 +!macroend diff --git a/src-tauri/tauri.conf.json b/src-tauri/tauri.conf.json index 7335e73..0509432 100644 --- a/src-tauri/tauri.conf.json +++ b/src-tauri/tauri.conf.json @@ -10,7 +10,8 @@ "type": "downloadBootstrapper" }, "nsis": { - "installMode": "currentUser" + "installMode": "currentUser", + "installerHooks": "./nsis/hooks.nsh" }, "wix": { "bannerPath": "wix/banner.bmp",