WiX: How to restart the explorer.exe immediately?

廉价感情. 提交于 2020-03-23 12:00:26

问题


I am a beginner in case of packaging of software. I am using cpack + Wix. I tried to find helpful information or a good documentation about util:RestartResource, but could not find any awnser to my question.

Issue: I have to install a ShellExtension which needs a restart of explorer.exe after setting some registry values. Because of that i use the command (https://wixtoolset.org/documentation/manual/v3/xsd/util/restartresource.html):

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

Everything nearly works like expected. Explorer.exe will be killed as expected but the restart of the explorer.exe will be triggered after the user is finishing the installation. That is to unpleasant, because explorer.exe disappears till the user clicks the finalize button of the installation. I would like a direct restart of the explorer after the registry values was set. I know this should be possible, because if WiX is triggering a restart of the explorer.exe by himself, it will be executed immediately and does not wait till the installation was finished. What is the trick? I tried already CustomActions and placing util:RestartResource at different position of the WiX-Code (I am desperate.).

[EDIT] I am analyzing the logs of the installation. And i realized that by default a Restart Manager is called at the beginning of progress and closed himself before the final Dialog. If i add a ProcessName to RestartResource it opens another Restart Manager which closed himself after the final dialog. Need to find out how to call RestartResource like the default RestartResource.

[EDIT2] I guess util:RestartResource is buggy. At the moment i crawl throw the WiX implementation code and MSI documentation and normally you should register all RestartResources before the state "InstallValidate". And that is exactly what WiX is trying to do in 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>

Because after this state MsiRestartManagerSessionKey will be terminated. And WiX tries to use this key in case of the registration of a RestartResource. But what i see inside of the logs is, that my util:RestartResource call will always executed after the "InstallValidate" state. And the log already says at this point, that the MsiRestartManagerSessionKey was terminated earlier (after "InstallValidate" state). That is from my point of view against the MSI policy.

[EDIT3] It is not buggy. I will post an awnser.


回答1:


A way to "restart explorer" is to do a system restart. You can use the Forcereboot element for this.

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.

More details can be found here: https://wixtoolset.org/documentation/manual/v3/xsd/wix/forcereboot.html

Aside: forcing a windows process that you don't own to restart seems dangerous. It's probably not supported natively with WiX because you probably shouldn't do it. :)




回答2:


It is not possible to do what i want with util:RestartResource. Because util:RestartResource writes into the installation database which Process needs to be restarted. (the position of util:RestartResource inside of the xml file does not have any affect of the scheduled shutdown and restart)

A CustomAction exist which is calling WixRegisterRestartResources (part of the WixUtilExtension.dll) before the "InstallValidate" state. That is exactly what is needed to register the process to the RestartManager of MSI with the MsiRestartManagerSessionKey. The restart processes will be extracted from the installation database. The RestartManager of MSI is shutting down all processes after the InstallValidate state. Sadly it is restarting all processes when the MSI process is completely finished and not earlier. That means it always will be triggered after user is pushing the Finish button in the FinalDialog. It is not changeable, because that is logic inside of the MSI Installer workflow.

I tried to implement a custom action which register himself to the MsiRestartManagerSessionKey and try to restart all processes before the EndDialog, but the RestartManager of MSI is denying all kind of this requests (some kind of Session error). And that is part of the MSI design, because the MSI Installer is removing the property MsiRestartManagerSessionKey after the InstallValidate state. They dont want that you can access the RestartManager after the InstallValidate state.

At the end i was implementing my own RestartManager with a CustomAction in C++ and later when i was realizing in C# the code is more clean i implemented it in C#. A good explanation how this could work you will find here: http://community.bartdesmet.net/blogs/bart/archive/2006/11/12/Exploring-Windows-Vista_2700_s-Restart-Manager-in-C_2300_.aspx



来源:https://stackoverflow.com/questions/60342822/wix-how-to-restart-the-explorer-exe-immediately

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!