I have a Windows .bat script which needs to be run from a NSIS installer at runtime.
The script is invoked as follows:
; Debug Messages to check values set correctly
MessageBox MB_OK "Script ${INSTDIR}\script\settingsLocation.bat"
MessageBox MB_OK "INSTDIR $INSTDIR "
MessageBox MB_OK "SettingsDirType $SettingsDirType"
MessageBox MB_OK "SettingsDirName $SettingsDirName"
MessageBox MB_OK "Calling script ${INSTDIR}\script\settingsLocation.bat $INSTDIR $SettingsDirType $SettingsDirName"
nsExec::ExecToStack 'CMD.exe /C ""${INSTDIR}\script\settingsLocation.bat"" ""${INSTDIR}"" $SettingsDirType $SettingsDirName'
; Check result status and output
Pop $0
MessageBox mb_ok "CMDout 0=$0"
Pop $0
MessageBox mb_ok "CMD Out 1=$0"
Using the above, the variable $INSTDIR
is not expanded, so not surprising the command fails to find the script.
$INSDIR
is "C:\Program Files (x86)\Prog Name"
(three spaces).
But I use the following (replace the ""
with "
):
nsExec::ExecToStack 'CMD.exe /C "${INSTDIR}\script\settingsLocation.bat" "${INSTDIR}" $SettingsDirType $SettingsDirName'
I get :
'C:\Program' is not recognized as an internal command, operable program or batch file.
Clearly I'm falling between the 2 stools of non expansion and full expanion ignoring quotes.
How can I preserve the quotes such that the command would run as if it were typed manually as follows:
"C:\Program Files (x86)\Prog Name\script\settingsLocation.bat" "C:\Program Files (x86)\Prog Name" DTYPE DNAME
Update 1 (following Anders's reply):
I tried the following mod:
nsExec::ExecToStack 'CMD.exe /C "$INSTDIR\script\settingsLocation.bat" "$INSTDIR" $SettingsDirType $SettingsDirName'
i.e change ${INSTDIR}
to $INSTDIR
This gives :
'C:\Program' is not recognized as a internal or external command
Update 2
Tried escaping the inner double quotes as follows:
nsExec::ExecToStack 'CMD.exe /C \"$INSTDIR\script\settingsLocation.bat\" \"$INSTDIR\" $SettingsDirType $SettingsDirName'
But this gave:
'\"C:\Program Files\....\" is not a recognised as an internal; or external command,
Update 3 (Resolved!!)
Following further help from Anders below, adding the if 1==1
bit finally got it working:
nsExec::ExecToStack 'CMD.exe /C if 1==1 "$INSTDIR\script\settingsLocation.bat" "$INSTDIR" $SettingsDirType $SettingsDirName'
Instdir is a variable, not a define, so you must use $InstDir
, not ${InstDir}
.
CMD.exe has crazy quote handling and will sometimes remove your quotes but there is a little workaround for that:
nsExec::ExecToStack 'CMD.exe /C if 1==1 "c:\path with spaces\app.exe" param1 "par am 2"'