Silently executing a PowerShell script from WiX Hangs PowerShell
Note: This question is also posted on the WiX Users mailing list.
I am trying to silently execute a PowerShell script from a WiX produced MSI. However, anytime I run the installer PowerShell hangs. Interestingly enough, according to the installer logs the PowerShell script appears to run successfully. Additionally, if I kill the PowerShell process via Task Manager, the installer cancels the installation and rolls back any changes.
PowerShell Script Contents
# @param website The website under which the module should be compiled and registered.
# @param name The name of the module to be registered.
# @param assembly The assembly name, version, culture and public key token to be compiled.
# @param assemblyType The fully qualified assemebly type to be registered.
param([string]$website = "website", [string]$name = "name", [string]$assembly = "assembly", [string]$assemblyType= "assemblyType")
import-module webadministration
add-webconfiguration /system.web/compilation/assemblies "IIS:\sites\$website" -Value @{assembly="$assembly"}
new-webmanagedmodule -Name "$name" -Type "$assemblyType" -PSPath "IIS:\sites\$website"
WiX Custom Action Contents : Attempt 1
My first attempt at this was to use the & special character to execute the script.
<CustomAction Id="RegisterHttpModulePSCmd"
Property="RegisterHttpModulePowerShellProperty"
Value=""C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" &'C:\Program Files (x86)\My Company\Scripts\register-httpmodule.ps1' -website 'Default Web Site' -name 'MyCustomModule' -assembly 'MyCompany.Product.Feature, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx' -assemblyType 'MyCompany.Product.Feature.MyModule'"
Execute="immediate" />
<CustomAction Id="RegisterHttpModulePowerShellProperty"
BinaryKey="WixCA"
DllEntry="CAQuietExec64"
Execute="deferred"
Return="check"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="RegisterHttpModulePSCmd" After="CostFinalize">NOT Installed</Custom>
<Custom Action="RegisterHttpModulePowerShellProperty" After="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
WiX Custom Action Contents : Attempt 2
My second attempt was to use the -File argument to execute the script.
<CustomAction Id="RegisterHttpModulePSCmd"
Property="RegisterHttpModulePowerShellProperty"
Value=""C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe" -NoLogo -NonInteractive -NoProfile -File "C:\Program Files (x86)\My Company\Scripts\register-httpmodule.ps1" -website "Default Web Site" -name "MyCu开发者_如何学JAVAstomModule" -assembly "MyCompany.Product.Feature, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx" -assemblyType "MyCompany.Product.Feature.MyModule""
Execute="immediate" />
<CustomAction Id="RegisterHttpModulePowerShellProperty"
BinaryKey="WixCA"
DllEntry="CAQuietExec64"
Execute="deferred"
Return="check"
Impersonate="no" />
<InstallExecuteSequence>
<Custom Action="RegisterHttpModulePSCmd" After="CostFinalize">NOT Installed</Custom>
<Custom Action="RegisterHttpModulePowerShellProperty" After="InstallFiles">NOT Installed</Custom>
</InstallExecuteSequence>
Both approaches seem to work as they make modifications to the desired web.config file, however, both approaches hang PowerShell and thus the installer.
Additional Information
I modified the PowerShell script to print out the version information and not perform any other actions. The MSI log files then display the following:
MSI (s) (D4:78) [10:26:31:436]: Hello, I'm your 32bit Elevated custom action server.
CAQuietExec64:
CAQuietExec64:
CAQuietExec64: Name : ConsoleHost
CAQuietExec64: Version : 2.0
CAQuietExec64: InstanceId : 62b0349c-8d16-4bd1-94e5-d1fe54a9ff54
CAQuietExec64: UI : System.Management.Automation.Internal.Host.InternalHostUserI
CAQuietExec64: nterface
CAQuietExec64: CurrentCulture : en-US
CAQuietExec64: CurrentUICulture : en-US
CAQuietExec64: PrivateData : Microsoft.PowerShell.ConsoleHost+ConsoleColorProxy
CAQuietExec64: IsRunspacePushed : False
CAQuietExec64: Runspace : System.Management.Automation.Runspaces.LocalRunspace
It is at this point that the installer appears to have stopped as PowerShell does not exit. When I kill PowerShell manually with Task Manager the next few log messages are:
CAQuietExec64: Error 0x80070001: Command line returned an error.
CAQuietExec64: Error 0x80070001: CAQuietExec64 Failed CustomAction RegisterHttpModulePowerShellProperty returned actual error code 1603 (note this may not be 100% accurate if translation happened inside sandbox) Action ended 10:27:10: InstallFinalize. Return value 3.
How do I silently execute a PowerShell script from Wix without hanging PowerShell?
I saw several posts like this one while searching on an unrelated issue and found an answer. Bottom line: include the flag -InputFormat None
in your command line.
Have you tried adding the keyword exit
to the end of the script?
I came across a similar situation with a C# project I've been working on. After building the project, I invoke PowerShell in the <AfterBuild>
target using MSBuild's <Exec>
task, specifying the script to run. If the script did not include the exit
keyword, VS2010 "hangs" - which is to say it's actually waiting for PowerShell to complete its task, while PowerShell waits for user input.
If you open up Task Manager or SysInternals Process Explorer, you will see powershell.exe
running as if nothing's wrong. If you kill the process, VS2010 (i.e. MSBuild) throws an error.
So you will need to tell PowerShell that you are done with it by adding exit
to the script it runs, and all should be well again.
精彩评论