PowerShell support: Difference between revisions
(Initial version) |
m (moved Execute PowerShell script or command to PowerShell support) |
Revision as of 18:16, 7 January 2014
Author: CharlesB (talk, contrib) |
Description
These macros simplify PowerShell use in NSIS, and overcomes a bug of PowerShell v2, [described here], and [reported here]).
PowerShellExec and PowerShellExecLog respectively the script output on the stack and in the log window The same goes for PowerShellExecFile and PowerShellExecFileLog, which are used to execute a PowerShell script file.
If execution fails, the error level is set to 2.
How to use
Save the script in a file named psexec.nsh, and place it next to your .nsi (or in the NSIS include directory). Then in your script, put an !include psexec.nsh, and call it like this
${PowerShellExec} "echo 'hello powershell'" Pop $R1 ;$R1 is "hello powershell" InitPluginsDir SetOutput $PLUGINSDIR\Powershell File script.ps1 ${PowerShellExecFileLog} "$PLUGINSDIR\Powershell\script.ps1"
In your PS commands, remember to escape the dollar sign by doubling it:
${PowerShellExec} "echo $$ProgramFiles"
Pitfalls
Be aware that as long as the installer is a 32 bit process, the PowerShell interpreter is also in 32 bit. This can cause redirections in filesystem, registry and environment variables when running or 64 bit systems (see https://en.wikipedia.org/wiki/WoW64)
Also I found that executing a file directly from $PLUGINSDIR caused errors in script execution, and that saving it in a $PLUGINSDIR subfolder prevented the errors.
The Script
!ifndef PSEXEC_INCLUDED !define PSEXEC_INCLUDED !include nsexec.nsh !macro PowerShellExecMacro PSCommand InitPluginsDir ;Save command in a temp file Push $R1 FileOpen $R1 $PLUGINSDIR\tempfile.ps1 w FileWrite $R1 "${PSCommand}" FileClose $R1 Pop $R1 !insertmacro PowerShellExecFileMacro "$PLUGINSDIR\tempfile.ps1" !macroend !macro PowerShellExecLogMacro PSCommand InitPluginsDir ;Save command in a temp file Push $R1 FileOpen $R1 $PLUGINSDIR\tempfile.ps1 w FileWrite $R1 "${PSCommand}" FileClose $R1 Pop $R1 !insertmacro PowerShellExecFileLogMacro "$PLUGINSDIR\tempfile.ps1" !macroend !macro PowerShellExecFileMacro PSFile !define PSExecID ${__LINE__} Push $R0 nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "${PSFile}" ' Pop $R0 ;return value is first on stack ;script output is second on stack, leave on top of it IntCmp $R0 0 finish_${PSExecID} SetErrorLevel 2 finish_${PSExecID}: Exch ;now $R0 on top of stack, followed by script output Pop $R0 !undef PSExecID !macroend !macro PowerShellExecFileLogMacro PSFile !define PSExecID ${__LINE__} Push $R0 nsExec::ExecToLog 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "${PSFile}" ' Pop $R0 ;return value is on stack IntCmp $R0 0 finish_${PSExecID} SetErrorLevel 2 finish_${PSExecID}: Pop $R0 !undef PSExecID !macroend !define PowerShellExec `!insertmacro PowerShellExecMacro` !define PowerShellExecLog `!insertmacro PowerShellExecLogMacro` !define PowerShellExecFile `!insertmacro PowerShellExecFileMacro` !define PowerShellExecFileLog `!insertmacro PowerShellExecFileLogMacro` !endif
Version History
- [Update 2014-01-07]
- Initial version