2

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.

Trafo
  • 71
  • 7

2 Answers2

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. :)

Robert P
  • 15,707
  • 10
  • 68
  • 112
  • You are sure it is not natively supported? Because WiX is automatically doing it, if the ShellExtension.dll is used by the explorer.exe and WiX tries to uninstall the dll. The user has then the option to reboot or restart the explorer. This restart happens directly and is not delayed till the uninstall process is finished. I want exactly this behavior. Additionally i can not use the Forcereboot option, because the installer should have the option noreboot, which can be a configure option of the user. Additionally software like SublimeText 3 are restarting the explorer by default. – Trafo Feb 21 '20 at 16:54
  • I am not sure. That said, just because one installer "does it", doesn't mean the action is natively supported with WiX, it just means the author of the installer has figured out a way to make Windows do what they want. If it's not a natively supported feature and it is a workaround, those tend to break over time since they're not officially supported. – Robert P Feb 21 '20 at 17:09
  • Sorry for this question, but i dont find a hint, that this is not natively supported. Because the *util:RestartResource* functionality exists and could be used. And i thought this function was introduced, because Microsoft wants to avoid restarts in the future and this function works great with explorer.exe, because it is restarting all open explorer.exe windows again after restart (that is great). Did i missed something? (https://wixtoolset.org/documentation/manual/v3/xsd/util/restartresource.html) – Trafo Feb 21 '20 at 17:18
  • Again, not sure. :) I wish you luck! – Robert P Feb 21 '20 at 17:42
  • 1
    The Best Practices way of restarting Explorer.exe is to reboot the system after the install. Just because RestartResource is available doesn't really mean that you should restart a dedicated Windows process as part. – Doc Feb 22 '20 at 19:22
  • I found out the root cause of my problem. The RestartManager does not have any scope. Any process which is scheduled to be restarted, will be restarted after the installation is finished. But the last ExitDialog window is very sadly still part of the Installation. So the installation is finished after the user is pressing the finish button. :( And it seems to be not possible to show GUI after the installation is finished, like successfully installed. At the moment the only solution is to skip the ExitDialog. – Trafo Feb 24 '20 at 18:15
0

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

Trafo
  • 71
  • 7