From ddddaad9a1a4ebc7b3b7833ffd8f38f5eb554031 Mon Sep 17 00:00:00 2001 From: f321x Date: Fri, 13 Jun 2025 17:04:36 +0200 Subject: [PATCH] block windows installer if Electrum is still running Adds a check to the Windows nsis installer and uninstaller that will show an error popup if Electrum is still running to prevent a broken installation that happen if the installer only partly overwrites the existing installation (see #6748). This works by trying to open the .exe files in the Electrum installation directory in append mode, if Electrum is still running the installer will not be able to open the .exe and the check fails. Based on https://github.com/Electron-Cash/Electron-Cash/pull/2185 --- contrib/build-wine/electrum.nsi | 63 +++++++++++++++++++++++++++++++++ 1 file changed, 63 insertions(+) diff --git a/contrib/build-wine/electrum.nsi b/contrib/build-wine/electrum.nsi index a42a66884..6aa4ce22b 100644 --- a/contrib/build-wine/electrum.nsi +++ b/contrib/build-wine/electrum.nsi @@ -87,6 +87,55 @@ !insertmacro MUI_LANGUAGE "English" +;-------------------------------- +;Functions + +!macro CreateEnsureNotRunning prefix operation + +Function ${prefix}EnsureNotRunning + ; pop the directory to check from the stack into $R0 + Pop $R0 + ; if the dir at $R0 doesn't exist, jump to nodir + IfFileExists "$R0" 0 nodir + ; Find all .exe files in the directory, $1 is the handle, $2 is the filename + FindFirst $1 $2 "$R0\*.exe" + IfErrors noexe 0 + + checkloop: + ; Skip checking the uninstaller if we are the uninstaller to avoid locking the uninstaller itself + !if "${prefix}" == "un." + StrCmp $2 "Uninstall.exe" skipfile 0 + !endif + + ; Check if we can append to the .exe file. If we can't that means it is still running. + retryopen: + FileOpen $0 "$R0\$2" a + IfErrors 0 closeexe + MessageBox MB_RETRYCANCEL "Can not ${operation} because $2 is still running. Close it and retry." /SD IDCANCEL IDRETRY retryopen + FindClose $1 + Abort + closeexe: + FileClose $0 + + skipfile: + ; Find next .exe file + FindNext $1 $2 + IfErrors done 0 + Goto checkloop + + done: + FindClose $1 + + noexe: + nodir: +FunctionEnd + +!macroend + +; The function has to be created twice, once for the installer and once for the uninstaller +!insertmacro CreateEnsureNotRunning "" "install" +!insertmacro CreateEnsureNotRunning "un." "uninstall" + ;-------------------------------- ;Installer Sections @@ -99,6 +148,14 @@ Function .onInit SetErrorLevel 740 ;ERROR_ELEVATION_REQUIRED Quit ${EndIf} + + ; Check if already installed and ensure the process is not running if it is + ReadRegStr $R0 HKCU "Software\${PRODUCT_NAME}" "" + IfErrors noinstdir 0 + Push $R0 + Call EnsureNotRunning + noinstdir: + ClearErrors FunctionEnd Section @@ -175,3 +232,9 @@ Section "Uninstall" DeleteRegKey HKCU "Software\${PRODUCT_NAME}" DeleteRegKey HKCU "${PRODUCT_UNINST_KEY}" SectionEnd + +Function UN.onInit + ; Ensure the process is not running in the uninstallation directory + Push $INSTDIR + Call un.EnsureNotRunning +FunctionEnd