从 WiX 静默执行 PowerShell 脚本会挂起 PowerShell

发布于 2024-10-01 14:25:05 字数 4892 浏览 0 评论 0原文

注意:此问题也发布在 WiX 用户邮件列表上.

我正在尝试从 WiX 生成的 MSI 静默执行 PowerShell 脚本。但是,每当我运行安装程序时,PowerShell 就会挂起。有趣的是,根据安装程序日志,PowerShell 脚本似乎运行成功。此外,如果我通过任务管理器终止 PowerShell 进程,安装程序将取消安装并回滚所有更改。

PowerShell 脚本内容

# @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 自定义操作内容:尝试 1

我的第一次尝试是使用 &执行脚本的特殊字符。

<CustomAction Id="RegisterHttpModulePSCmd"
              Property="RegisterHttpModulePowerShellProperty"
              Value="&quot;C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe&quot; &amp;'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 自定义操作内容:尝试 2

我的第二次尝试是使用 -File 参数来执行脚本。

<CustomAction Id="RegisterHttpModulePSCmd"
              Property="RegisterHttpModulePowerShellProperty"       
              Value="&quot;C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe&quot; -NoLogo -NonInteractive -NoProfile -File &quot;C:\Program Files (x86)\My Company\Scripts\register-httpmodule.ps1&quot; -website &quot;Default Web Site&quot; -name &quot;MyCustomModule&quot; -assembly &quot;MyCompany.Product.Feature, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx&quot; -assemblyType &quot;MyCompany.Product.Feature.MyModule&quot;"
              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>

这两种方法似乎都可以在对所需的 web.config 文件进行修改时起作用,但是,这两种方法都会挂起 PowerShell 并因此挂起安装程序。

其他信息

我修改了 PowerShell 脚本以打印出版本信息并且不执行任何其他操作。然后 MSI 日志文件显示以下内容:

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

此时,安装程​​序似乎已停止,因为 PowerShell 未退出。当我使用任务管理器手动终止 PowerShell 时,接下来的几条日志消息是:

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.

如何在不挂起 PowerShell 的情况下从 Wix 静默执行 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 "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>

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?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

薆情海 2024-10-08 14:25:05

我在搜索不相关的问题时看到了几篇类似的帖子,并发现了 回答。底线:在命令行中包含标志 -InputFormat None

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.

薄凉少年不暖心 2024-10-08 14:25:05

您是否尝试过将关键字 exit 添加到脚本末尾?

我在我一直从事的 C# 项目中遇到了类似的情况。生成项目后,我使用 MSBuild 的 任务在 目标中调用 PowerShell,指定要运行的脚本。如果脚本不包含 exit 关键字,VS2010 将“挂起”——也就是说,它实际上正在等待 PowerShell 完成其任务,而 PowerShell 则等待用户输入。

如果您打开任务管理器或SysInternals Process Explorer,您将看到< code>powershell.exe 运行就好像没有任何问题一样。如果终止该进程,VS2010(即 MSBuild)会抛出错误。

因此,您需要通过向 PowerShell 运行的脚本添加 exit 来告诉 PowerShell 您已完成操作,一切都会恢复正常。

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.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文