Files
bible-app/build/installer.nsh
T

75 lines
5.1 KiB
NSIS
Raw Permalink Normal View History

2026-09-24 13:05:20 -04:00
!macro customInstall
; Local AI (llama.cpp) requires the Microsoft VC++ 2015-2022 x64 runtime.
; Fresh Windows / TV PCs often do not have it preinstalled.
IfFileExists "$INSTDIR\resources\app.asar.unpacked\vendor\redist\vc_redist.x64.exe" 0 +2
ExecWait '"$INSTDIR\resources\app.asar.unpacked\vendor\redist\vc_redist.x64.exe" /install /quiet /norestart' $0
!macroend
; ---------------------------------------------------------------------------------------------------
; Replaces electron-builder's "is the app running?" check (customCheckAppRunning). Runs at the start of
; installing, BEFORE the old version is removed and before any file is copied.
;
; The stock check only looks for "Bible App.exe". But the app also starts programs from its own folder
; - the local AI server (llama-server.exe), speech (whisper), the upscaler - and if the app is closed
; hard, those are left running. They hold their files open, so copying the new version fails and the
; installer says "Bible App cannot be closed. Please close it manually and click Retry" even though
; the app is plainly closed, and Retry can never succeed. So:
; 1. ask the app to close (it then stops the AI server itself), and give it a moment;
; 2. force-close anything named Bible App.exe that is still there;
; 3. force-close the app's own helper programs by name (plain taskkill, nothing to go wrong);
; 4. as a backstop, force-close EVERY program running from this install folder, whatever its name.
; Step 4 matches by folder, via WMI (works from this 32-bit installer on 64-bit Windows, where a
; 32-bit process cannot read a 64-bit process's path). The folder travels in an environment variable
; so a quote or space in it can never break the command, and it refuses to act on a bare drive.
; No question is asked first: installing this version replaces the app, which is what was asked for.
; ---------------------------------------------------------------------------------------------------
!macro customCheckAppRunning
DetailPrint `Closing "${PRODUCT_NAME}"...`
nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "USERNAME eq %USERNAME%"`
Pop $0
Sleep 2500
nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /f /t /im "${APP_EXECUTABLE_FILENAME}" /fi "USERNAME eq %USERNAME%"`
Pop $0
nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /f /t /im llama-server.exe /im whisper-cli.exe /im realesrgan-ncnn-vulkan.exe /fi "USERNAME eq %USERNAME%"`
Pop $0
System::Call 'Kernel32::SetEnvironmentVariable(t "BIBLEAPP_INSTDIR", t "$INSTDIR")'
StrCpy $1 "$SYSDIR\WindowsPowerShell\v1.0\powershell.exe"
${If} ${FileExists} "$WINDIR\Sysnative\WindowsPowerShell\v1.0\powershell.exe"
StrCpy $1 "$WINDIR\Sysnative\WindowsPowerShell\v1.0\powershell.exe"
${EndIf}
StrCpy $2 `"$1" -NoProfile -NonInteractive -ExecutionPolicy Bypass -Command "$$r = $$env:BIBLEAPP_INSTDIR.TrimEnd('\'); if ($$r.Split('\').Count -lt 2) { exit }; $$d = $$r + '\'; Get-CimInstance Win32_Process | Where-Object { $$_.ExecutablePath -and $$_.ExecutablePath.StartsWith($$d, [StringComparison]::OrdinalIgnoreCase) } | ForEach-Object { Stop-Process -Id $$_.ProcessId -Force -ErrorAction SilentlyContinue }"`
DetailPrint `Closing anything else still running from "${PRODUCT_NAME}"'s folder...`
nsExec::Exec $2
Pop $0
Sleep 1000
!insertmacro bibleAppSkipDamagedUninstaller SHELL_CONTEXT
!insertmacro bibleAppSkipDamagedUninstaller HKCU
!macroend
; ---------------------------------------------------------------------------------------------------
; Versions 1.4.35 - 1.4.37 were built on macOS before build/installerIcon.ico existed, and their
; uninstallers are damaged: they fail NSIS's own integrity check ("Installer integrity check has
; failed"). electron-builder rebuilds the uninstaller in JavaScript on macOS and leaves out NSIS's
; icon patch, so whenever the installer and uninstaller icons differ (NSIS's two defaults do), the
; checksum is wrong. An update runs the PREVIOUS version's uninstaller first, so those versions could
; never be updated: the damaged uninstaller fails, and the installer reports "Bible App cannot be
; closed" (it also cannot be uninstalled from Windows Settings).
;
; For exactly those versions, the old uninstaller is not run: its UninstallString is cleared, so
; electron-builder's uninstallOldVersion finds nothing to run, and the new files are copied over the
; old ones. This installer then writes a fresh, valid uninstaller and registry entry. Every other
; version still goes through the normal uninstall-then-install path.
; ---------------------------------------------------------------------------------------------------
!macro bibleAppSkipDamagedUninstaller ROOT
ReadRegStr $3 ${ROOT} "${UNINSTALL_REGISTRY_KEY}" DisplayVersion
${If} $3 == "1.4.35"
${OrIf} $3 == "1.4.36"
${OrIf} $3 == "1.4.37"
DetailPrint `Version $3's uninstaller is damaged; installing over it instead.`
DeleteRegValue ${ROOT} "${UNINSTALL_REGISTRY_KEY}" UninstallString
!ifdef UNINSTALL_REGISTRY_KEY_2
DeleteRegValue ${ROOT} "${UNINSTALL_REGISTRY_KEY_2}" UninstallString
!endif
${EndIf}
!macroend