Wix stop service on uninstall/upgrade: prevent “restart popup” (file-in-use situation)

倾然丶 夕夏残阳落幕 提交于 2019-11-28 12:42:36
Kiran Hegde

You have a couple of options to resolve this issue:

-Disable "Restart Manager" by making use of MSIRESTARTMANAGERCONTROL= "Disable" in the property table. This would kick in the legacy "FilesInUse" dialog box. In your case, The FilesinUse dialog might also not be displayed (since services do not have a window associated with them) The "FilesinUse" dialog box does not list processes which do not have a window associated with them. So, in your case, disabling the Restart Manager, might not display any dialogs(neither FilesInUse nor RestartManager).

However, this would also mean that a reboot might be required, not necessarily because of your services but due to some other process which might be holding your files in use. If you think that there could be no other process other than your own services holding files, then go ahead and follow this approach . If you think that there could be other processes, other than your services holding files, then having "Restart Manager" enabled is ideal. Not having "Restart Manager" will either result in one of the things:

-Display the Legacy FilesInUse dialog asking you to shut down the processes listed in the dialog. This might result in you having to shut down these processes via a custom action.

Both the "RestartManager" and "FilesInUse" dialogs are displayed by the "InstallValidate" standard action. If you want to suppress both of these dialogs, then ensure that your custom action is scheduled before "InstallValidate" standard action. There is a catch here. Scheduling such a custom action before InstallValidate would have to be an immediate mode custom action(You cannot have deferred mode custom actions before "IntsallFinalize"). So , in cases where you are not running as an administrator(such as in UAC enabled scenarios), you might not have the necessary privileges to shut down applications. So , a restart might be required.

-You can also shut down applications using the using the WiX util extensions CloseApplication() function. Evaluate your scenario and do what is right for you.

I think I might be late to the party, but here's the solution. The Installer team blog post explains how the Restart Manager decides whether to pop up the files in use dialog. Specifically (Windows Installer-Restart Manager Interaction in Detail section, item 3.b.):

If the package is authored such that the services detected by RM would be shutdown because of the authoring of the Service* tables then those services will not be displayed in the files-in-use dialogs.

(italics are mine). Helpful but not immediately helpful, because such that is not really elaborated. But since my service caused the same problem as described by the OP with

<ServiceControl Stop="uninstall" ... />

I just changed the value to both

<ServiceControl Stop="both" ... />

which was probably the only remaining thing that could make it “such that,” and boom, fireworks, magic:

MSI (s) (50:A0) [21:50:30:352]: RESTART MANAGER: Detected that application with id 6408, friendly name 'XXXX', service short name 'xxxx', of type RmService and status 1 holds file[s] in use.
MSI (s) (50:A0) [21:50:30:352]: RESTART MANAGER: Detected that the service xxxx will be stopped due to a service control action authored in the package before the files are updated. So, we will not attempt to stop this service using Restart Manager

It appears that both flags msidbServiceControlEventStop (0x002) and msidbServiceControlEventUninstallStop (0x020) need to be set in the ServiceControl table to make the RM happily conclude that the service is going to stop before files are updated.


In retrospect this makes sense. Since the uninstallation part during the upgrade is carried out using the old cached MSI database, RM does not look into it to see what is going to happen when the related product is uninstalled. Strictly speaking, there may be multiple products to uninstall, and the Installer does not require anywhere that these related products (those found by the FindRelatedProducts action, including the old version of the same upgrade code) be in fact related to the service that one is controlling in the current package. So it does not care about the service action on uninstall as scripted in the current package (it does not apply to the install action anyway!). For the sake of consistency, it requires a simple and straightforward evidence that the service is going to be stopped before the files in use are overwritten, gathering such evidence from the current package alone.

So it is quite likely that the RM cares about the msidbServiceControlEventStop (0x002) flag only during the installation.

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