WiX:在RemoveExistingProducts之前停止服务或运行提升的CustomAction以在RemoveExistingProducts之前停止进程

时间:2015-06-25 08:50:13

标签: wix windows-installer

我在重大升级时遇到了问题。安装程序包含一项服务,在升级时我得到一个弹出窗口,说明需要重新启动才能完成安装过程。

为了防止出现这种情况,我实际上只需要在执行RemoveExistingProducts(而不是InstallValidate)之前停止服务。

MajorUpgrade位于InstallInitialize之后且包裹InstallPrivileges="elevated"

我有两个案例:

案例1 ServiceInstall通过

安装该服务
<Component Id="myservice_Service" Guid="*">
            <File Id="myservice.exe" KeyPath="yes" Vital="yes"
                  Source="SourceDir\bin\myservice.exe"/>
            <ServiceInstall Id="myservice_ServiceInstall" Type="ownProcess"
                            Vital="yes" Name="myservice" DisplayName="myservice Service"
                            Description="myservice Service" Start="auto" Account=".\LocalSystem"
                            ErrorControl="ignore" Interactive="no" Arguments="--run"/>
            <ServiceControl Id="myservice_ServiceControl" Name="myservice" Wait="yes" Stop="uninstall"/>
        </Component>

ServiceControlInstallValidate被调用之前没有停止服务。即使说停止=&#34;两者都是&#34;。所以弹出窗口出现了。请注意,安装程序不会启动该服务。

我发现的合理帖子(摘录):

案例2 :该服务由CustomAction安装(有一些原因可以解释为什么不通过ServiceInstall进行操作)。 在这种情况下,我必须调用可执行文件来停止服务(&#34; myservice.exe --stop&#34;)。为此,它变得棘手,因为由于ICE63,在调用CustomAction之前不允许安排RemoveExistingProducts。那么,我怎么能实现这个呢?

到目前为止,我已阅读过以下帖子:

bootstrapper exe是没有选择的,因为我需要生成一个普通的MSI。

我在这里找到了类似的未解决问题:Wix Installer Problem: Why does RestartManager mark Service as RMCritical and not RMService

2 个答案:

答案 0 :(得分:2)

InstallValidate之后的ServiceControl顺序无关紧要。如果在InstallValidate中检测到服务的文件正在使用情况,但服务在ServiceControl表中在卸载时停止,则Windows会合理地推迟使用任何文件情况以查看实际发生的情况。如果你从ServiceControl中取出它,你将失去这个潜在有用的功能。请注意,您可以独立于ServiceInstall使用ServiceControl - 它们不会绑定在一起,因此如果服务可以很好地与ServiceControl一起使用,则不必运行exe来停止服务。

这种情况的一个常见原因就是服务行为不端。 Wait = yes赢了,永远等待,根据文档只有30秒。因此,服务必须响应控制消息,告诉它停止。即使服务被停止&#34;这并不意味着该过程已经消失,只是它不再作为服务运行。如果实际终止进程需要一段时间,那么Windows别无选择,只能显示正在使用的文件。这些事情很难调试,因为时间问题通常是,但如果是我,我会仔细检查服务关闭代码。

另请注意,在升级方案中,您可能需要stop = both。如果InstallValidate(在您的传入升级中)没有在ServiceControl中看到安装停止并且正在使用文件,那么您将获得该文件在使用中的问题。 InstallValidate没有预见到何时可以运行RemoveExistingProducts,然后在另一个MSI中查找可能阻止正在使用的文件的ServiceControl。

答案 1 :(得分:0)

案例2的解决方案是:

<DirectoryRef Id='INSTALLDIR'>
  <Component Id='StopService' Guid='{0913D365-8EC0-424A-939E-0F04E99D2ACA}' KeyPath='yes'>
    <ServiceControl Id='StopServiceControl' Name='ServiceName' Stop='uninstall' Wait='yes'/>
  </Component>
</DirectoryRef>

在这种情况下,不会出现FileInUse dialaog。