Skip to content

Commit 5ca7c3a

Browse files
Filip Mösnerpanther7
authored andcommitted
feat(nsis): terminate only processes running in installation folder
Modified the process termination logic in NSIS scripts to only kill application processes that are running from the installation directory. This prevents accidental termination of processes with the same name running from other locations during installation or update.
1 parent 7dbc6c7 commit 5ca7c3a

File tree

2 files changed

+60
-22
lines changed

2 files changed

+60
-22
lines changed

.changeset/flat-trees-return.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
"app-builder-lib": minor
3+
---
4+
5+
feat(nsis): terminate only processes running in installation folder

packages/app-builder-lib/templates/nsis/include/allowOnlyOneInstallerInstance.nsh

Lines changed: 55 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,11 @@
77
Var pid
88
!endif
99

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+
1015
# http://nsis.sourceforge.net/Allow_only_one_installer_instance
1116
!macro ALLOW_ONLY_ONE_INSTALLER_INSTANCE
1217
BringToFront
@@ -37,14 +42,51 @@
3742
!endif
3843
!macroend
3944

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}
4890
!macroend
4991

5092
!macro _CHECK_APP_RUNNING
@@ -55,7 +97,7 @@
5597
Sleep 300
5698
${endIf}
5799

58-
!insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0
100+
!insertmacro FIND_PROCESS "$INSTDIR" $R0
59101
${if} $R0 == 0
60102
${if} ${isUpdated}
61103
# allow app to exit without explicit kill
@@ -69,12 +111,7 @@
69111

70112
DetailPrint `Closing running "${PRODUCT_NAME}"...`
71113

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}"
78115
# to ensure that files are not "in-use"
79116
Sleep 300
80117

@@ -84,16 +121,12 @@
84121
loop:
85122
IntOp $R1 $R1 + 1
86123

87-
!insertmacro FIND_PROCESS "${APP_EXECUTABLE_FILENAME}" $R0
124+
!insertmacro FIND_PROCESS "$INSTDIR" $R0
88125
${if} $R0 == 0
89126
# wait to give a chance to exit gracefully
90127
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
97130
${If} $R0 == 0
98131
DetailPrint `Waiting for "${PRODUCT_NAME}" to close.`
99132
Sleep 2000

0 commit comments

Comments
 (0)