WiX:如何立即重启 explorer.exe?

WiX: How to restart the explorer.exe immediately?

我是软件打包方面的初学者。我正在使用 cpack + Wix。我试图找到有关 util:RestartResource 的有用信息或良好文档,但找不到任何 awnser 来解决我的问题。

问题: 我必须安装一个 ShellExtension,它需要在设置一些注册表值后重新启动 explorer.exe。因此,我使用命令 (https://wixtoolset.org/documentation/manual/v3/xsd/util/restartresource.html):

<util:RestartResource ProcessName="explorer.exe"/>

几乎一切都按预期进行。 Explorer.exe 将按预期终止,但 explorer.exe 将在用户完成安装后重新启动。这是令人不快的,因为 explorer.exe 会消失,直到用户单击安装的完成按钮。我想在设置注册表值后直接重新启动资源管理器。我知道这应该是可能的,因为如果 WiX 自己触发 explorer.exe 重启,它会立即执行,不会等到安装完成。诀窍是什么?我已经尝试了 CustomActions 并将 util:RestartResource 放在 WiX 代码的不同位置(我很绝望。)。

[编辑] 我正在分析安装日志。我意识到默认情况下,在进度开始时会调用重启管理器,并在最终对话框之前自行关闭。如果我将 ProcessName 添加到 RestartResource,它会打开另一个重启管理器,该管理器在最后一个对话框后自行关闭。需要找出如何调用 RestartResource 就像默认的 RestartResource.

[EDIT2] 我猜 util:RestartResource 有问题。目前我抓取了 WiX 实现代码和 MSI 文档,通常你应该在状态 "InstallValidate" 之前注册所有 RestartResources。而这正是 WiX 在 UtilExtension_Platform.wxi:

中试图做的
  <Fragment>
    <CustomAction Id="WixRegisterRestartResources$(var.Suffix)" BinaryKey="WixCA" DllEntry="WixRegisterRestartResources$(var.Suffix)" Execute="immediate" Return="check" SuppressModularization="yes" />

    <InstallExecuteSequence>
      <Custom Action="WixRegisterRestartResources$(var.Suffix)" Before="InstallValidate" Overridable="yes" />
    </InstallExecuteSequence>
  </Fragment>

因为在此状态之后MsiRestartManagerSessionKey 将被终止。在 RestartResource 注册的情况下,WiX 会尝试使用此密钥。但是我在日志中看到的是,我的 util:RestartResource 调用将始终在 "InstallValidate" 状态之后执行。并且此时日志已经表明,MsiRestartManagerSessionKey 已提前终止(在 "InstallValidate" 状态之后)。这是我反对 MSI 政策的观点。

[EDIT3] 它不是越野车。我要 post 一个遮阳篷。

"restart explorer" 的一种方法是重新启动系统。您可以为此使用 Forcereboot 元素。

Prompts the user for a restart of the system during the installation. Special actions don't have a built-in sequence number and thus must appear relative to another action. The suggested way to do this is by using the Before or After attribute. InstallExecute and InstallExecuteAgain can optionally appear anywhere between InstallInitialize and InstallFinalize.

可以在此处找到更多详细信息:https://wixtoolset.org/documentation/manual/v3/xsd/wix/forcereboot.html

旁白:强制重新启动不属于您的 windows 进程似乎很危险。 WiX 本身可能不支持它,因为您可能不应该这样做。 :)

无法使用 util:RestartResource 执行我想要的操作。因为 util:RestartResource 写入需要重启进程的安装数据库。 (util:RestartResource在xml文件中的位置对定时关机和重启没有任何影响)

存在 CustomAction,它在 [之前调用 WixRegisterRestartResourcesWixUtilExtension.dll 的一部分) =43=]状态。这正是使用 MsiRestartManagerSessionKey 将进程注册到 MSI 的 RestartManager 所需要的。重新启动过程将从安装数据库中提取。 MSI 的 RestartManager 正在关闭 InstallValidate 状态后的所有进程。遗憾的是,当 MSI 进程完全完成而不是更早时,它正在重新启动所有进程。这意味着它总是会在用户按下 FinalDialog 中的 Finish 按钮后触发。它不可更改,因为这是 MSI 安装程序工作流程中的逻辑。

我试图实现一个自定义操作,将自己注册到 MsiRestartManagerSessionKey 并尝试在 EndDialog 之前重启所有进程,但 MSI 的 RestartManager 拒绝所有类型的此类请求(某种会话错误)。这是 MSI 设计的一部分,因为 MSI 安装程序在 InstallValidate 状态之后删除 属性 MsiRestartManagerSessionKey。他们不希望您可以在 InstallValidate 状态后访问 RestartManager。

最后,我在 C++ 中使用 CustomAction 实现了我自己的 RestartManager,后来当我意识到在 C# 中代码更干净时,我在 C# 中实现了它。您可以在这里找到一个很好的解释:http://community.bartdesmet.net/blogs/bart/archive/2006/11/12/Exploring-Windows-Vista_2700_s-Restart-Manager-in-C_2300_.aspx