!ifndef nsProcess::FindProcess!include "nsProcess.nsh"!endif!ifmacrondef customCheckAppRunning!include "getProcessInfo.nsh"Var pid!endif# http://nsis.sourceforge.net/Allow_only_one_installer_instance!macro ALLOW_ONLY_ONE_INSTALLER_INSTANCEBringToFront!define /ifndef SYSTYPE_PTR p ; NSIS v3.0+System::Call 'kernel32::CreateMutex(${SYSTYPE_PTR}0, i1, t"${APP_GUID}")?e'Pop $0IntCmpU $0 183 0 launch launch ; ERROR_ALREADY_EXISTSStrLen $0 "$(^SetupCaption)"IntOp $0 $0 + 1 ; GetWindowText count includes \0StrCpy $1 "" ; Start FindWindow with NULLloop:FindWindow $1 "#32770" "" "" $1StrCmp 0 $1 notfoundSystem::Call 'user32::GetWindowText(${SYSTYPE_PTR}r1, t.r2, ir0)'StrCmp $2 "$(^SetupCaption)" 0 loopSendMessage $1 0x112 0xF120 0 /TIMEOUT=2000 ; WM_SYSCOMMAND:SC_RESTORE to restore the window if it is minimizedSystem::Call "user32::SetForegroundWindow(${SYSTYPE_PTR}r1)"notfound:Abortlaunch:!macroend!macro CHECK_APP_RUNNING!ifmacrodef customCheckAppRunning!insertmacro customCheckAppRunning!else!insertmacro _CHECK_APP_RUNNING!endif!macroend!macro FIND_PROCESS _FILE _ERR!ifdef INSTALL_MODE_PER_ALL_USERS${nsProcess::FindProcess} "${_FILE}" ${_ERR}!else# find process owned by current usernsExec::Exec `"$SYSDIR\cmd.exe" /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" /FO csv | "$SYSDIR\find.exe" "${_FILE}"`Pop ${_ERR}!endif!macroend!macro _CHECK_APP_RUNNING${GetProcessInfo} 0 $pid $1 $2 $3 $4${if} $3 != "${APP_EXECUTABLE_FILENAME}"${if} ${isUpdated}# allow app to exit without explicit killSleep 300${endIf}!insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0${if} $R0 == 0${if} ${isUpdated}# allow app to exit without explicit killSleep 1000Goto doStopProcess${endIf}MessageBox MB_OKCANCEL|MB_ICONEXCLAMATION "$(appRunning)" /SD IDOK IDOK doStopProcessQuitdoStopProcess:DetailPrint `Closing running "${PRODUCT_NAME}"...`# https://github.com/electron-userland/electron-builder/issues/2516#issuecomment-372009092!ifdef INSTALL_MODE_PER_ALL_USERSnsExec::Exec `taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"`!elsensExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"`!endif# to ensure that files are not "in-use"Sleep 300# Retry counterStrCpy $R1 0loop:IntOp $R1 $R1 + 1!insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0${if} $R0 == 0# wait to give a chance to exit gracefullySleep 1000!ifdef INSTALL_MODE_PER_ALL_USERSnsExec::Exec `taskkill /f /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"`!elsensExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /f /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"`!endif!insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0${If} $R0 == 0DetailPrint `Waiting for "${PRODUCT_NAME}" to close.`Sleep 2000${else}Goto not_running${endIf}${else}Goto not_running${endIf}# App likely running with elevated permissions.# Ask user to close it manually${if} $R1 > 1MessageBox MB_RETRYCANCEL|MB_ICONEXCLAMATION "$(appCannotBeClosed)" /SD IDCANCEL IDRETRY loopQuit${else}Goto loop${endIf}not_running:${endIf}${endIf}!macroend