How to call PowerShell in NSIS

2019-06-25 01:48发布

问题:

I am trying to run PowerShell in NSIS. when I run the NSIS script:

!include "x64.nsh"

Name "nsExec Test"

OutFile "nsExecTest.exe"

ShowInstDetails show

Section "Output to variable"

    nsExec::ExecToStack 'powershell -Command "& {Import-Module }" ServerManager'
    Pop $0 # return value/error/timeout
    Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
    DetailPrint '"ImportModules" printed: $1'
    DetailPrint "       Return value: $0"

    nsExec::ExecToStack 'powershell -Command "& {Get-WindowsFeature}" Desktop-Experience'
    Pop $0 # return value/error/timeout
    Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
    DetailPrint '"GetWindowsFeature" printed: $1'
    DetailPrint "       Return value: $0"
SectionEnd

When it executed to "Import-Module ServerManager", The PowerShell was started up(It can be seen in TaskManager processes). But nsExecTest.exe was hanging over.

I have googled this problem, and found a workaround for Java. https://blogs.oracle.com/vaibhav/entry/not_as_easy_as_we

Anyone has ideas for this problem in NSIS?

Updated: I simplify my test script.

!include "x64.nsh"

Name "nsExec Test"
OutFile "nsExecTest.exe"
ShowInstDetails show

Section "Output to variable"
${If} ${RunningX64}
    ${DisableX64FSRedirection}

    nsExec::ExecToStack 'powershell.exe "& "Import-Module ServerManager"'
    Pop $0 # return value/error/timeout
    Pop $1 # printed text, up to ${NSIS_MAX_STRLEN}
    DetailPrint '"ImportModules" printed: $1'
    DetailPrint " Return value: $0"
    DetailPrint ""

    ${EnableX64FSRedirection}
${Else}
${EndIf}
SectionEnd

回答1:

As far as I found out, AaronLS's answer didn't work for me, I found two workarounds for this problem, related to a bug in PowerShell v2 reported here (but never fixed):

  • Upgrade to PowerShell v3
  • Run the script from a file in NSIS, and specify inputformat none. For a very strange reason you have to leave two spaces before the last quote of nsExec::ExecToStack:

    SetOutPath "$pluginsdir\NSISTemp"
    File script.ps1
    nsExec::ExecToStack 'powershell -inputformat none -ExecutionPolicy RemoteSigned -File "$pluginsdir\NSISTemp\script.ps1"  '
    

Using the macros I've written here, it is just a matter of ${PowerShellExec} "echo 'hello powershell'".



回答2:

Been awhile since I used NSIS, so I'm just guessing based on syntax I saw elsewhere:

nsExec::ExecToStack 'powershell.exe "& "Import-Module ServerManager"'

Take out the second command, and just test with the first and get that working first, then you can be sure you have the first command right.

Also try adding < NUL to the end of your and/or my command line:

nsExec::ExecToStack 'powershell -Command "& {Import-Module }" ServerManager < NUL'
nsExec::ExecToStack 'powershell.exe "& "Import-Module ServerManager" < NUL'

I'm not sure if it needs to be inside the double quotes or not. It can hang if it's waiting for you to finish providing input as if you were running it interactively:

http://epeleg.blogspot.com/2010/06/solution-to-powershell-never-exists.html