如何在正确访问 Windows 注册表的情况下在 WiX 中启动 PowerShell? [英] How to start PowerShell in WiX with proper access to Windows Registry?

查看:70
本文介绍了如何在正确访问 Windows 注册表的情况下在 WiX 中启动 PowerShell?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

更新

有趣的是,如果我运行 32 位 powershell 来运行脚本,它会给我同样的错误.看起来 32 位的 powershell 无法访问 64 位的注册表树?我尝试使用 WixQuietExec64 但它给出了同样的错误.我还尝试提供 powershell 的完整路径 (C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe) 以确保安装程序启动 64 位版本,但仍然给出了同样的错误...看起来这可能是由 MSI 安装程序本身是 32 位引起的??

Interesting, if I run 32bit powershell to run the script, it gives me the same error. It looks like the 32bit powershell has no access to the 64 bit registry tree? I tried using WixQuietExec64 but it gave the same error. I also tried providing the full path of the powershell (C:\Windows\system32\WindowsPowerShell\v1.0\powershell.exe) to ensure the installer to launch the 64bit version, but that STILL gave the same error... It looks like this might be caused by the MSI installer itself being 32bit??

MSI (s) (4C:C0) [14:25:49:955]: Hello, I'm your 32bit Elevated Non-remapped custom action server.

原帖

我有以下 test.ps1 脚本:

$exchangeroot = "HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\"
$allexchanges = Get-ChildItem -Path Registry::$exchangeroot -Name | Where-Object { $_ -match "^V.." }
$sorted = $allexchanges | Sort-Object -descending
If ($sorted.Count -gt 1) { $latest = $sorted[0] } Else { $latest = $sorted }
$setup = $exchangeroot + $latest + "\Setup"
$properties = Get-ItemProperty -Path Registry::$setup
$properties

在普通的 PowerShell 窗口中运行脚本会产生以下输出:

Running the script in a normal PowerShell windows yields the following output:

PS C:\Program Files (x86)\TrustValidator Exchange Server Plugin> .\test.ps1

Required machine-level settings.          : 1
Services                                  : C:\Program Files\Microsoft\Exchange Server\V15
NewestBuild                               : 10845
CurrentBuild                              : 710737954
Information Store Service                 : 1
Messaging and Collaboration Event Logging : 1
MsiInstallPath                            : C:\Program Files\Microsoft\Exchange Server\V15\
...

所以它有效.现在从 WiX 安装程序启动 PowerShell 并执行脚本,它不会生成相同的结果:

So it works. Now launching PowerShell from WiX installer and executing the script, it doesn't generate the same result:

WixQuietExec:  Get-ItemProperty : Cannot find path 
WixQuietExec:  'HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\v15\Setup' because it 
WixQuietExec:  does not exist.
WixQuietExec:  At C:\Program Files (x86)\TrustValidator Exchange Server Plugin\test.ps1:10 
WixQuietExec:  char:16
WixQuietExec:  +     $properties = Get-ItemProperty -Path Registry::$setup
WixQuietExec:  +                   ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
WixQuietExec:      + CategoryInfo          : ObjectNotFound: (HKEY_LOCAL_MACH...erver\v15\Set 
WixQuietExec:     up:String) , ItemNotFoundException
WixQuietExec:      + FullyQualifiedErrorId : PathNotFound,Microsoft.PowerShell.Commands.GetIt 
WixQuietExec:     emPropertyCommand

现在,如果我们观察到错误消息,就好像它可以访问树直到 HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\,因为我的脚本会搜索并列出所有版本,所以到那时 v15 必须可以访问,但是当它试图更深入地获取 ItemProperty 时,它不能.

Now if we observe the error message, it is as though it has access of the tree up until HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\ExchangeServer\, because my script would search and list all the versions, so v15 has to be accessible up to that point, however when it tries to go deeper to get the ItemProperty, it can't.

这让我相信,从 WiX 安装程序启动 PowerShell 时,我可能遗漏了什么......?

This lead me to believe that perhaps I'm missing something when launching my PowerShell from WiX installer...?

这是我的 wxs 文件中的内容:

This is what's in my wxs file:

<SetProperty Id="InstallPlugin"
     Before ="InstallPlugin"
     Sequence="execute"
     Value ="&quot;powershell.exe&quot; -Command &quot;cd '[INSTALLFOLDER]'; &amp; '[#TestPS1]' ; exit $$($Error.Count)&quot;" />
<CustomAction Id="InstallPlugin" BinaryKey="WixCA" DllEntry="WixQuietExec" Execute="deferred" Return="ignore" Impersonate="no" />

以下是我已经尝试或仔细检查过的项目列表:

Below are a list of items that I've already tried or double checked:

  • 我尝试了 -NoProfile-ExecutionPolicy ByPass-Version 2.0 的不同组合,但仍然不行.
  • 我已经以 InstallPrivileges="elevated"
  • 的身份运行安装程序
  • 我已经将 CustomAction 作为 Execute="deferred"Impersonate="no"
  • 运行
  • 我已经尝试过 AdminImage="yes"
  • 我试过设置 <Property Id="MSIUSEREALADMINDETECTION" Value="1"/>
  • I've tried different combinations of -NoProfile, -ExecutionPolicy ByPass, -Version 2.0 and still no good.
  • I'm already running the installer as InstallPrivileges="elevated"
  • I'm already running the CustomAction as Execute="deferred" and Impersonate="no"
  • I've tried with AdminImage="yes"
  • I've tried setting <Property Id="MSIUSEREALADMINDETECTION" Value="1" />

任何其他线索将不胜感激.:(

Any other clue would be appreciated. :(

推荐答案

哦...天哪...

好的,我终于让它工作了.实际上有几个问题,这些问题的解决方案实际上是我从多个 SO 问题中收集的零碎信息.

Ok I finally got it working. There were actually several problems and the solutions for these problems were actually in bits and pieces of information that I gather from across multiple SO questions.

总结一下,这就是我想要做的:

To recap, here is what I was trying to do:

  1. 从 WiX 启动一个 powershell 来运行我的安装脚本.
  2. 我的脚本在 Windows 注册表(需要 64 位)中搜索已安装 Exchange Server 的位置
  3. 我的脚本从安装位置加载 Exchange 命令行管理程序 (EMS) 脚本(需要 64 位和适当的用户)
  4. 在 EMS 会话下,我的脚本运行其他脚本的早午餐以注册 Exchange 插件

问题 1)

无论我做什么,WiX 安装程序总是以 32 位启动我的 powershell,这与设置 Platform="x64"Win64="yes"、甚至 WixQuietExec64.我什至在 Visual Studio 中将安装程序构建为 x64,将其他一切 构建为 x64.

No matter what I did, the WiX installer always launches my powershell in 32bit, this is regardless of setting Platform="x64", Win64="yes", and even WixQuietExec64. I even built the installer in Visual Studio as x64 and everything else as x64.

解决办法是直接引用sysnative powershell,它必须是SetProperty中的sysnative.

The solution is to directly reference the sysnative powershell, it has to be sysnative in the SetProperty.

C:\Windows\sysnative\WindowsPowerShell\v1.0\powershell.exe

我之前确实尝试过,但认为它不起作用,但根本原因被下面的问题 2 掩盖了.

I actually did tried this before, and thought it wasn't working, but the root cause was being masked by Problem 2 below.

问题 2)

在我读到的任何地方,他们都说您需要使用 Execute="deferred" Impersonate="No" 运行.我相信如果你没有做任何时髦的事情,这确实适用于大多数情况.但是,我不得不 模拟.我发现 WiX 安装程序会以用户 NT Authority/System 提升的身份运行您的 CA.这把我搞砸了,因为我试图获取的 Exchange Management Shell 脚本基本上会使用您的凭据并尝试与 Exchange Server 建立会话......当然你不能以 NT 权限/系统

Everywhere I read, they said you need to run with Execute="deferred" Impersonate="No". I believe this would indeed work for the most cases if you are not doing anything funky. However, I had to Impersonate. I discovered that the WiX installer would run your CA as elevated with user NT Authority/System. This screwed me over because the Exchange Management Shell script I was trying to source would basically use your credential and try to establish a session with the Exchange Server... and of course you can't connect as NT Authority/System!

解决方案是使用 Impersonate="yes" 以便 WiX 安装程序以提升的身份和您当前登录的用户运行您的 CA.我一直觉得您必须使用 Impersonate="no" 使用 Execute="deferred" 时... 但你没有.

The solution is to use Impersonate="yes" so that the WiX installer would run your CA as elevated AND the user you are currently logged in. I always had the impression that you must use Impersonate="no" when using Execute="deferred"... but you don't.

我放弃了几天的故障排除,然后回到它并让它工作.帮助我解决这个问题的 2 个最有用的命令实际上是:

I gave up troubleshoot this for a few days and then went back to it and got it working. The 2 most helpful commands that helped me figured this out were actually:

  • 呜呜
  • Get-ChildItem env:(检查 PROCESSOR_ARCHITECTURE)

这篇关于如何在正确访问 Windows 注册表的情况下在 WiX 中启动 PowerShell?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆