PowerShell support: Difference between revisions
(Initial version) |
m (→How to use: formatting) |
||
(6 intermediate revisions by 2 users not shown) | |||
Line 3: | Line 3: | ||
== Description == | == Description == | ||
These macros simplify PowerShell use in NSIS, and | These macros simplify PowerShell use in NSIS, and overcome a bug of PowerShell v2, [http://forums.winamp.com/showthread.php?p=2969465 described here], and [http://connect.microsoft.com/PowerShell/feedback/details/572313/powershell-exe-can-hang-if-stdin-is-redirected reported here]). | ||
PowerShellExec and PowerShellExecLog respectively the script output on | PowerShellExec and PowerShellExecLog respectively place the script output on the stack and in the log window. | ||
the stack and in the log window | |||
The same goes for PowerShellExecFile and PowerShellExecFileLog, which | The same goes for PowerShellExecFile and PowerShellExecFileLog, which are used to execute a PowerShell script file. | ||
are used to execute a PowerShell script file. | |||
If execution fails, the error level is set to 2. | If execution fails, the error level is set to 2. | ||
Line 14: | Line 13: | ||
== How to use == | == 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 | 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 <code>!include psexec.nsh</code>, and call it like this | ||
<highlight-nsis>${PowerShellExec} "echo 'hello powershell'" | <highlight-nsis>${PowerShellExec} "echo 'hello powershell'" | ||
Line 32: | Line 31: | ||
Be aware that as long as the installer is a 32 bit process, the PowerShell interpreter | 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 | is also in 32 bit. This can cause redirections in filesystem, registry and environment | ||
variables when running or 64 bit systems (see | variables when running or 64 bit systems (see [[:wikipedia: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. | Also I found that executing a file directly from [[Reference/$PLUGINSDIR|$PLUGINSDIR]] caused errors in script execution, and that saving it in a [[Reference/$PLUGINSDIR|$PLUGINSDIR]] subfolder prevented the errors. | ||
== The Script == | == The Script == | ||
Line 40: | Line 39: | ||
!ifndef PSEXEC_INCLUDED | !ifndef PSEXEC_INCLUDED | ||
!define PSEXEC_INCLUDED | !define PSEXEC_INCLUDED | ||
!macro PowerShellExecMacro PSCommand | !macro PowerShellExecMacro PSCommand |
Latest revision as of 09:53, 14 January 2016
Author: CharlesB (talk, contrib) |
Description
These macros simplify PowerShell use in NSIS, and overcome a bug of PowerShell v2, described here, and reported here).
PowerShellExec and PowerShellExecLog respectively place 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 wikipedia: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 !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