|
7 | 7 | Var pid
|
8 | 8 | !endif
|
9 | 9 |
|
| 10 | +Var CmdPath = "$SYSDIR\cmd.exe" |
| 11 | +Var FindPath = "$SYSDIR\find.exe" |
| 12 | +Var PowerShellPath = "$SYSDIR\WindowsPowerShell\v1.0\powershell.exe" |
| 13 | +Var IsPowerShellAvailable |
| 14 | + |
10 | 15 | # http://nsis.sourceforge.net/Allow_only_one_installer_instance
|
11 | 16 | !macro ALLOW_ONLY_ONE_INSTALLER_INSTANCE
|
12 | 17 | BringToFront
|
|
37 | 42 | !endif
|
38 | 43 | !macroend
|
39 | 44 |
|
40 |
| -!macro FIND_PROCESS _FILE _ERR |
41 |
| - !ifdef INSTALL_MODE_PER_ALL_USERS |
42 |
| - ${nsProcess::FindProcess} "${_FILE}" ${_ERR} |
43 |
| - !else |
44 |
| - # find process owned by current user |
45 |
| - nsExec::Exec `"$SYSDIR\cmd.exe" /c tasklist /FI "USERNAME eq %USERNAME%" /FI "IMAGENAME eq ${_FILE}" /FO csv | "$SYSDIR\find.exe" "${_FILE}"` |
46 |
| - Pop ${_ERR} |
47 |
| - !endif |
| 45 | +!macro IS_POWERSHELL_AVAILABLE _RETURN |
| 46 | + # Try running PowerShell with a simple command |
| 47 | + nsExec::ExecToStack `"$PowerShellPath" -NoProfile -NonInteractive -Command "exit 0"` |
| 48 | + Pop ${_RETURN} # Return code (0 = success, other = error) |
| 49 | + |
| 50 | + ${If} ${_RETURN} == 0 |
| 51 | + # PowerShell is available, check if it's not blocked by policies |
| 52 | + nsExec::ExecToStack `"$PowerShellPath" -NoProfile -NonInteractive -Command "if ((Get-ExecutionPolicy -Scope Process) -eq 'Restricted') { exit 1 } else { exit 0 }"` |
| 53 | + Pop ${_RETURN} |
| 54 | + ${EndIf} |
| 55 | + |
| 56 | + # For safety, convert any non-zero result to 1 |
| 57 | + ${If} ${_RETURN} != 0 |
| 58 | + StrCpy ${_RETURN} 1 |
| 59 | + ${EndIf} |
| 60 | +!macroend |
| 61 | + |
| 62 | +!insertmacro IS_POWERSHELL_AVAILABLE $IsPowerShellAvailable |
| 63 | + |
| 64 | +!macro FIND_PROCESS _PATH _FILENAME _RETURN |
| 65 | + ${If} $IsPowerShellAvailable == True |
| 66 | + nsExec::Exec `"$PowerShellPath" -Command "if ((Get-Process | Where-Object {$$_.Path -and $$_.Path.StartsWith('${_PATH}')}).Count -gt 0) { exit 0 } else { exit 1 }"` |
| 67 | + Pop ${_RETURN} |
| 68 | + ${Else} |
| 69 | + !ifdef INSTALL_MODE_PER_ALL_USERS |
| 70 | + ${nsProcess::FindProcess} "${_FILENAME}" ${_RETURN} |
| 71 | + !else |
| 72 | + # find process owned by current user |
| 73 | + nsExec::Exec `"$CmdPath" /c tasklist /fi "USERNAME eq %USERNAME%" /fi "IMAGENAME eq ${_FILENAME}" /fo csv | "$FindPath" "${_FILENAME}"` |
| 74 | + Pop ${_RETURN} |
| 75 | + !endif |
| 76 | + ${EndIf} |
| 77 | +!macroend |
| 78 | + |
| 79 | +!macro KILL_PROCESS _PATH _FILENAME _RETURN |
| 80 | + ${If} $IsPowerShellAvailable == 0 |
| 81 | + nsExec::Exec `"$PowerShellPath" -Command "Get-Process | ?{$$_.Path -and $$_.Path.StartsWith('${_PATH}')} | Stop-Process -Force"` |
| 82 | + Pop ${_RETURN} |
| 83 | + ${Else} |
| 84 | + !ifdef INSTALL_MODE_PER_ALL_USERS |
| 85 | + nsExec::Exec `taskkill /im "${_FILENAME}" /fi "PID ne $pid"` |
| 86 | + !else |
| 87 | + nsExec::Exec `"$CmdPath" /c taskkill /im "${_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"` |
| 88 | + !endif |
| 89 | + ${EndIf} |
48 | 90 | !macroend
|
49 | 91 |
|
50 | 92 | !macro _CHECK_APP_RUNNING
|
|
55 | 97 | Sleep 300
|
56 | 98 | ${endIf}
|
57 | 99 |
|
58 |
| - !insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0 |
| 100 | + !insertmacro FIND_PROCESS "$INSTDIR" $R0 |
59 | 101 | ${if} $R0 == 0
|
60 | 102 | ${if} ${isUpdated}
|
61 | 103 | # allow app to exit without explicit kill
|
|
69 | 111 |
|
70 | 112 | DetailPrint `Closing running "${PRODUCT_NAME}"...`
|
71 | 113 |
|
72 |
| - # https://github.com/electron-userland/electron-builder/issues/2516#issuecomment-372009092 |
73 |
| - !ifdef INSTALL_MODE_PER_ALL_USERS |
74 |
| - nsExec::Exec `taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"` |
75 |
| - !else |
76 |
| - nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"` |
77 |
| - !endif |
| 114 | + !insertmacro KILL_PROCESS "$INSTDIR" "${APP_EXECUTABLE_FILENAME}" |
78 | 115 | # to ensure that files are not "in-use"
|
79 | 116 | Sleep 300
|
80 | 117 |
|
|
84 | 121 | loop:
|
85 | 122 | IntOp $R1 $R1 + 1
|
86 | 123 |
|
87 |
| - !insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0 |
| 124 | + !insertmacro FIND_PROCESS "$INSTDIR" $R0 |
88 | 125 | ${if} $R0 == 0
|
89 | 126 | # wait to give a chance to exit gracefully
|
90 | 127 | Sleep 1000
|
91 |
| - !ifdef INSTALL_MODE_PER_ALL_USERS |
92 |
| - nsExec::Exec `taskkill /f /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid"` |
93 |
| - !else |
94 |
| - nsExec::Exec `"$SYSDIR\cmd.exe" /c taskkill /f /im "${APP_EXECUTABLE_FILENAME}" /fi "PID ne $pid" /fi "USERNAME eq %USERNAME%"` |
95 |
| - !endif |
96 |
| - !insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0 |
| 128 | + !insertmacro KILL_PROCESS "$INSTDIR" "${APP_EXECUTABLE_FILENAME}" |
| 129 | + !insertmacro FIND_PROCESS "$INSTDIR" $R0 |
97 | 130 | ${If} $R0 == 0
|
98 | 131 | DetailPrint `Waiting for "${PRODUCT_NAME}" to close.`
|
99 | 132 | Sleep 2000
|
|
0 commit comments