卸载/升级时的Wix停止服务:阻止“重启弹出”(文件在用情况)

时间:2015-08-03 12:51:41

标签: wix windows-installer restartmanager

我遇到了这个问题,在卸载(或升级)时,重启管理器抱怨文件处于使用状态,因此强制重启:

RESTART MANAGER: Detected that application with id 7000, friendly name 'javaw.exe', of type RmCritical and status 1 holds file[s] in use.
RESTART MANAGER: Did detect that a critical application holds file[s] in use, so a reboot will be necessary.

RESTART MANAGER抱怨的服务是基于java的服务。该服务(此处称为myservice.exe)以递归方式启动java子进程:

myservice.exe - 运行
↳javaw.exe--someArguments
↳otherother.exe--someArguments
↳javaw.exe--someMoreArguments

服务定义的wix片段:

<DirectoryRef Id="BINDIR">
        <Component Id="myservice.exe" Guid="PUT-GUID-HERE">
            <File Id="myservice.exe" KeyPath="yes" Vital="yes"
                  Source="SourceDir\bin\myservice.exe"/>
            <ServiceInstall Id="MyService" Type="ownProcess"
                            Vital="yes" Name="MyService" DisplayName="My Service"
                            Description="My Service" Start="auto" Account=".\LocalSystem"
                            ErrorControl="normal" Interactive="no" Arguments="--run"/>
            <ServiceControl Id="MyService" Name="MyService" Wait="yes" Remove="uninstall" Stop="uninstall" Start="install"/>
        </Component>
</DirectoryRef>

现在,有趣的部分:

  • 安装时可以启动服务
卸载时

  • 如果没有运行,它将被删除
  • 如果正在运行,只是同意重新启动
    • 它确实在大约2-3秒内停止(我想通过StopServices操作)
    • 并成功删除(通过RemoveServices操作)

到目前为止,Service * Tables中的条目似乎对我有用。

ServiceControl-Table:
ServiceControl  Name       Event  Arguments  Wait  Component_
MyService       MyService  161               1     myservice.exe

ServiceInstall-Table:
ServiceInstall  Name       DisplayName  ServiceType StartType ErrorControl LoadOrderGroup Dependencies StartName Password Arguments Component_     Description
MyService       MyService  My Service   16          2         32769        .\LocalSystem                                  --run     myservice.exe  My Service


所以,要打破一切: 似乎Restart Manager无法识别java进程是子进程,并且将由Stop​​Services操作停止。

我在这里发现了一些类似的问题: https://www.mail-archive.com/wix-users@lists.sourceforge.net/msg57924.html
Wix Installer Problem: Why does RestartManager mark Service as RMCritical and not RMService

提前感谢您解决此问题的任何帮助!

2 个答案:

答案 0 :(得分:4)

您有几种方法可以解决此问题:

-Disable&#34;重启管理器&#34;通过使用MSIRESTARTMANAGERCONTROL =&#34;禁用&#34;在属性表中。这将带来遗产&#34; FilesInUse&#34;对话框。 在您的情况下,也可能不会显示FilesinUse对话框(因为服务没有与之关联的窗口)  &#34; FilesinUse&#34;对话框不会列出没有与之关联的窗口的进程。因此,在您的情况下,禁用重新启动管理器可能不会显示任何对话框(既不是FilesInUse也不是RestartManager)。

但是,这也意味着可能需要重新启动,不一定是因为您的服务,而是由于某些其他进程可能会暂停您的文件。如果您认为除了您自己的服务保留文件之外不会有其他进程,那么请继续并遵循此方法。如果您认为可能有其他进程,而不是您的服务保存文件,那么有#34;重新启动管理器&#34; 已启用是理想选择。没有&#34;重启管理器&#34;将导致其中一件事:

- 显示Legacy FilesInUse对话框,要求您关闭对话框中列出的进程。这可能导致您必须通过自定义操作关闭这些进程。

&#34; RestartManager&#34;和&#34; FilesInUse&#34;对话框由&#34; InstallValidate&#34;显示。标准行动。如果要禁止这两个对话框,请确保在&#34; InstallValidate&#34;之前安排自定义操作。标准行动。这里有一个问题。在InstallValidate之前安排这样的自定义操作必须是立即模式自定义操作(在&#34之前不能有延迟模式自定义操作; IntsallFinalize&#34;)。因此,如果您没有以管理员身份运行(例如在启用UAC的情况下),您可能没有必要的权限来关闭应用程序。因此,可能需要重新启动。

- 您还可以使用WiX util扩展CloseApplication()函数关闭应用程序。 评估您的场景并做适合您的事情。

答案 1 :(得分:0)

我想我可能会迟到,但这是解决方案。 Installer team blog post解释了重启管理器如何决定是否弹出正在使用的文件对话框。具体而言( Windows Installer-Restart Manager交互详细信息部分,第3.b项):

  

如果程序包是由创建的,那么由于Service *表的创作而导致RM检测到的服务将被关闭,那么这些服务将不会显示在使用中的文件对话框中。

(斜体是我的)。有帮助,但没有立即帮助,因为这样并没有真正详细阐述。但由于我的服务引起了与OP所描述的相同的问题

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

我刚刚将值更改为both

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

这可能是唯一能让它“如此”的东西,以及热潮,烟花,魔法

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

似乎需要在ServiceControl table中设置两个标志 msidbServiceControlEventStop (0x002)和<​​strong> msidbServiceControlEventUninstallStop (0x020)让RM愉快地得出结论,服务将在文件更新之前停止。

回想起来,这是有道理的。由于升级期间的卸载部分是使用旧缓存的 MSI数据库执行的,因此RM不会查看它以查看卸载相关产品时会发生什么。严格来说,可能有多个产品要卸载,而安装程序不需要这些相关产品FindRelatedProducts action找到的那些产品),包括旧版本的相同升级代码) 实际上当前包中正在控制的服务相关。所以它并不关心当前包中脚本化的卸载服务操作(它不适用于安装操作!)。为了保持一致性,它需要一个简单而直接的证据,即在使用的文件被覆盖之前服务将被停止,仅从当前包中收集这些证据。

因此,RM很可能仅在安装期间关注 msidbServiceControlEventStop (0x002)标志。