4

我遇到了问题,卸载(或升级)时,重新启动管理器抱怨文件正在使用中,因此强制重新启动:

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 --run
   ↳ javaw.exe --someArguments
      ↳ someother.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


因此,分解所有内容: 似乎重新启动管理器没有识别出 java 进程是子进程并且将被 StopServices 操作停止。

我在这里发现了一些类似的问题: https
://www.mail-archive.com/wix-users@lists.sourceforge.net/msg57924.html Wix 安装程序问题:为什么 RestartManager 将服务标记为 RMCritical 而不是 RMService

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

4

2 回答 2

6

您有几个选项可以解决此问题:

- 通过使用属性表中的 MSIRESTARTMANAGERCONTROL=“禁用”禁用“重新启动管理器”。这将启动旧的“FilesInUse”对话框。在您的情况下,FilesinUse 对话框也可能不会显示(因为服务没有与之关联的窗口) “FilesinUse”对话框不会列出没有与之关联的窗口的进程。因此,在您的情况下,禁用重新启动管理器可能不会显示任何对话框(FilesInUse 和 RestartManager 都不显示)。

但是,这也意味着可能需要重新启动,这不一定是因为您的服务,而是由于其他一些可能正在使用您的文件的进程。如果您认为除了您自己的服务保存文件之外没有其他进程,那么请继续遵循此方法。如果您认为除了您的服务保存文件之外可能还有其他进程,那么启用“重新启动管理器”是理想的。没有“重新启动管理器”将导致以下情况之一:

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

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

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

于 2015-08-04T05:31:13.487 回答
1

我想我可能会迟到,但这是解决方案。安装程序团队博客文章解释了重新启动管理器如何决定是否弹出正在使用的文件对话框。具体来说(Windows Installer-Restart Manager Interaction in Detail部分,第 3.b. 项):

如果包的编写使得RM 检测到的服务将因编写 Service* 表而关闭,那么这些服务将不会显示在使用中的文件对话框中。

(斜体是我的)。有帮助但不会立即有帮助,因为没有真正详细说明。但是由于我的服务引起了与 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 表中设置标志 msidbServiceControlEventStop (0x002) 和 msidbServiceControlEventUninstallStop (0x020)使RM愉快断定服务将在文件更新之前停止。


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

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

于 2018-02-15T06:33:38.950 回答