PowerShell support: Difference between revisions

From NSIS Wiki
Jump to navigationJump to search
mNo edit summary
No edit summary
Line 5: Line 5:
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]]).  
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  

Revision as of 08:22, 8 January 2014

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 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
 
!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