Windows服务的WiX MajorUpgrade,保留.config并避免重新启动



我正在努力让MajorUpgrade、ServiceControl和.config文件能够很好地协同工作。在我的另一个问题之后,我现在又遇到了相反的问题。

以前,文件没有被覆盖,因为AssemblyFileVersions是静态的,所以我修复了这个问题1)现在,即使使用Schedule="afterInstallExecute",我的KeyPath='yes'.config文件仍被覆盖,即使现有文件修改日期与文件创建日期不同,并且它被设置为KeyPath。我目前必须覆盖.config文件,并在安装后重新启动服务。

2)即使我解决了这个问题,我仍然存在避免重新启动的问题。如果我说Schedule="afterInstallInitialize",那么我相信.config文件肯定会过早地与服务一起删除。如果我说Schedule="afterInstallExecute",那么服务不会停止,安装后需要重新启动。(没错,对吧?)在安装之前手动停止服务,让我避免重新启动。我想,添加net stop自定义操作可以取代ServiceControl,但要使所有条件都正确似乎很复杂。

3)作为奖励,我希望在升级过程中完全不删除该服务。我可以停止服务,替换二进制文件,然后重新启动服务吗?这将避免重新输入升级的服务帐户凭据。但当然,它仍然需要在第一次安装时安装,在删除功能时卸载。

这是它的肉(稍后也会捆起来,以防有什么问题):

<MajorUpgrade DowngradeErrorMessage="A newer version is already installed." 
              Schedule="afterInstallExecute" />
<ComponentGroup Id="ServiceCG">
    <Component Id="Service" Guid='*' Win64='yes' Directory='INSTALLDIR'>
        <File Id='ServiceEXE' Source='$(var.root)Service.exe' />
        <ServiceInstall Id="ServiceInstall"
                          Name="MyService"
                          DisplayName="My Server"
                          Type="ownProcess"
                          Start="auto"
                          ErrorControl="normal"
                          Description="My Server Service"
                          Interactive="no"
                          Account="[...]"
                          Password="[...]" />
        <ServiceControl Id="StopService" Name="MyService" Start="install" 
                        Stop="uninstall" Wait="yes" Remove="both" />
        <util:User Id="UpdateServiceAccountLogonAsService" UpdateIfExists="yes"
                   CreateUser="no" Name="[SERVICEACCOUNTFULL]" 
                   LogonAsService="yes"/>
    </Component>
    <Component Id="ServiceConfig" Guid='*' Win64='yes' Directory='INSTALLDIR'>
        <File Id='FileServiceConfig' KeyPath='yes' 
              Source='$(var.root)Service.exe.config' />
    </Component>
</ComponentGroup>

相关但未回答:

  • 阻止在WiX主要升级期间删除/安装服务-服务未停止

WiX版本3.8.1128.0

EDIT:似乎对同一问题的解释,或者至少对同一主题的解释,可能更容易理解:Msiexec:安装失败时自动回滚到以前的版本


你在这里碰到了几个MSI的核心使用问题。

  1. 文件版本控制:在安装过程中,默认文件覆盖模式(由REINSTALLMODE属性定义)不会替换默认版本相同的文件。这可以通过设置REINSTALLMODE="emus"来更改。这将用版本相同的文件替换文件。如果修改和创建日期不同,将保留未版本的文件
  2. 升级行为:正如Chris所说,由于主要的升级配置,看起来恢复为默认值的文件实际上会被卸载和重新安装。只有在InstallExecuteSequence中放置RemoveExistingProducts较晚的情况下,才能在主要升级中保留文件。然后,版本之间的共享文件永远不会被卸载,并且第1点中描述的文件版本控制规则适用于覆盖
  3. 服务配置保留:避免重新输入服务凭据信息是在InstallExecuteSequence早期卸载的主要升级的常见问题。换言之,该产品被卸载,然后重新安装,擦除更改的文件。我不推荐它,但有些人支持这个解决方案:如何在wix中进行重大升级时只停止而不卸载windows服务?(Rob Mensching是WIX和Orca的作者-我认为他建议将此解决方案作为一种选择,而不一定是一种建议。请在链接的帖子中询问以确定)。通过在InstallExecuteSequence中放置正确的组件引用和卸载,通常可以完全避免这个问题,因此,这是一种首选方法(正常的组件引用可以防止组件完全卸载,而保持服务设置和更改的配置文件不变-如果且仅当组件引用是正确的-请参阅下面对这一概念的描述)。然而,我的首选方法仍然是使用单独的MSI进行服务安装和配置如果您使用用户帐户运行服务,那么它是一个独立的部署单元,可以包含在引导程序中并自行更新,最棒的是:它不受任何其他应用程序更改或修补程序的干扰。最后,我想指出的是,出于安全和部署的原因,使用用户帐户运行服务不是一种推荐的方法

组件引用:指分配给MSI组件的GUID,以及它们在所有升级过程中必须如何匹配一个且始终只有一个(绝对)路径。这里有几个例子可以更好地讨论这个问题:在wix中更改我的组件GUID?

我没有提到将MSI组件安装服务设置为永久性以防止在卸载时删除的选项,原因很简单,这根本不是一个好的做法。然后,文件和注册将保留在最终卸载时,您需要自定义操作来清理。这是一种非常糟糕的做法,势必会导致大量额外的工作和悬空组件引用的问题。

文件创建/mod规则仅适用于安装/重新安装组件。它不会阻止卸载该组件。您的主要升级计划很早,这意味着之前的版本将被完全卸载,然后安装新版本。这就是为什么你的文件会在你不希望的时候被覆盖。请稍后安排RemoveExistingProducts以避免这个问题。

将"停止"属性设置为同时安装和卸载。这两个变化应该能解决你的问题。

相关内容

  • 没有找到相关文章

最新更新