如何在使用WixUI_Advanced时将RemoveExistingProducts更改为InstallFinalize之后?

时间:2018-01-03 19:26:55

标签: wix windows-installer

这是我的情景:

  • 使用Wix 3.6
  • 使用WixUI_Advanced对话框设置(添加能够在安装期间控制各个功能的功能)
  • NeverOverwrite="yes"组件设置web.config(以便安装后的本地更改不会丢失)

但是,安装程序似乎仍然在升级期间删除并重新安装web.config文件。

最好我可以告诉WixUI_Advanced对话框集具有以下配置:

<InstallExecuteSequence>
     <RemoveExistingProducts After="InstallInitialize"/>
</InstallExecuteSequence>

以下是安装中的日志片段:

MSI (s) (74:8C) [18:37:00:959]: Executing op: ActionStart(Name=InstallInitialize,,)
Action 18:37:00: InstallInitialize. 
...
Action 18:37:00: ProcessComponents. Updating component registration
...
Action 18:37:00: UnpublishFeatures. Unpublishing Product Features
...
UnpublishFeatures: Feature: ProductFeature
...
UnpublishFeatures: Feature: AdditionalFeature
...
MSI (s) (74:8C) [18:37:00:967]: Executing op: ActionStart(Name=RemoveFiles,Description=Removing files,Template=File: [1], Directory: [9])
Action 18:37:00: RemoveFiles. Removing files
MSI (s) (74:8C) [18:37:00:967]: Executing op: ProgressTotal(Total=2,Type=1,ByteEquivalent=175000)
MSI (s) (74:8C) [18:37:00:967]: Executing op: SetTargetFolder(Folder=C:\Program Files (x86)\MyTestApp\WebApp\)
MSI (s) (74:8C) [18:37:00:967]: Executing op: FileRemove(,FileName=web.config,,ComponentId={B4A12A8F-56A3-4DD1-A0BA-B9C39EB305FD})
RemoveFiles: File: web.config, Directory: C:\Program Files (x86)\MyTestApp\WebApp\
MSI (s) (74:8C) [18:37:00:968]: Verifying accessibility of file: web.config
MSI (s) (74:8C) [18:37:00:969]: Note: 1: 2318 2:  
MSI (s) (74:8C) [18:37:00:969]: Note: 1: 2318 2:  
MSI (s) (74:8C) [18:37:00:969]: Executing op: FileRemove(,FileName=somefile.txt,,ComponentId={B835CEF5-1A84-4C37-8CB0-BE983BAF73F9})
RemoveFiles: File: somefile.txt, Directory: C:\Program Files (x86)\MyTestApp\WebApp\
MSI (s) (74:8C) [18:37:00:970]: Verifying accessibility of file: somefile.txt
MSI (s) (74:8C) [18:37:00:970]: Note: 1: 2318 2:  
MSI (s) (74:8C) [18:37:00:970]: Note: 1: 2318 2:  
MSI (s) (74:8C) [18:37:00:971]: Executing op: ActionStart(Name=PublishProduct,Description=Publishing product information,)
Action 18:37:00: PublishProduct. Publishing product information
...
Action 18:37:00: RollbackCleanup. Removing backup files
RollbackCleanup: File: C:\Config.Msi\7cd65c.rbf
RollbackCleanup: File: C:\Config.Msi\7cd65d.rbf
MSI (s) (74:8C) [18:37:00:980]: Note: 1: 2318 2:  
MSI (s) (74:8C) [18:37:00:981]: Note: 1: 2318 2:  
MSI (s) (74:8C) [18:37:00:981]: No System Restore sequence number for this installation.
MSI (s) (74:8C) [18:37:00:981]: Unlocking Server
MSI (s) (74:8C) [18:37:00:985]: PROPERTY CHANGE: Deleting UpdateStarted property. Its current value is '1'.
Action ended 18:37:00: InstallFinalize. Return value 1.
Action ended 18:37:00: INSTALL. Return value 1.

如您所见,它会在web.config

之后删除InstallInitialize文件

当我尝试更改wxs文件时,添加:

<InstallExecuteSequence>
     <RemoveExistingProducts After="InstallFinalize"/>
</InstallExecuteSequence>

我明白了:

error LGHT0091: Duplicate symbol 'WixAction:InstallExecuteSequence/RemoveExistingProducts' found. This typically means that an Id is duplicated. Check to make sure all your identifiers of a given type (File, Component, Feature) are unique.

以下是我使用的Product.wxs文件:

<?xml version="1.0" encoding="UTF-8"?>
<Wix xmlns="http://schemas.microsoft.com/wix/2006/wi" xmlns:util="http://schemas.microsoft.com/wix/UtilExtension">
  <Product Id="*" Name="MyTestInstaller" Language="1033" Version="1.0.9.0" Manufacturer="Acme, Inc" UpgradeCode="6ca3779c-e8ce-42e8-bf81-3166bd96e585">
    <Package Id="*" InstallerVersion="301" Compressed="yes" InstallScope="perMachine" Platform="x64" InstallPrivileges="elevated" />

    <Upgrade Id="6ca3779c-e8ce-42e8-bf81-3166bd96e585">
      <UpgradeVersion Minimum="1.0.9.0" OnlyDetect="yes" Property="NEWERVERSIONDETECTED" />
      <UpgradeVersion OnlyDetect="no" Minimum="0.0.0.0" IncludeMinimum="yes" Maximum="1.0.9.0" Property="OLDERVERSIONBEINGUPGRADED" IgnoreRemoveFailure="yes">
      </UpgradeVersion>
    </Upgrade>

    <Condition Message="A later version of [ProductName] is already installed.">NOT NEWERVERSIONDETECTED</Condition>
    <Media Id="1" Cabinet="myapp.cab" EmbedCab="yes" />
    <MajorUpgrade DowngradeErrorMessage="A newer version of [ProductName] is already installed." />
    <Feature Id="ProductFeature" Title="MyTestInstaller" Level="1">
      <ComponentGroupRef Id="ProductComponents" />
    </Feature>
    <Feature Id="AdditionalFeature" Title="Additional Features" Level="10">
      <ComponentGroupRef Id="AdditionalComponents"/>
    </Feature>
    <Property Id="ApplicationFolderName" Value="MyTestApp"/>
    <!-- BEGIN: DISABLE THE Per User Install -->
    <Property Id="WixAppFolder" Value="WixPerMachineFolder"/>
    <WixVariable Id="WixUISupportPerUser" Value="0" />
    <!-- END: DISABLE THE Per User Install -->
    <UI>
      <UIRef Id="WixUI_Advanced" />
    </UI>
  </Product>

  <Fragment>
    <Directory Id="TARGETDIR" Name="SourceDir">
      <Directory Id="ProgramFilesFolder">
        <Directory Id="APPLICATIONFOLDER" Name="ICS">
          <Directory Id="WebApp" Name="WebApp">
            <Component Id="WEB.CONFIG" Guid="B4A12A8F-56A3-4DD1-A0BA-B9C39EB305FD" DiskId="1" NeverOverwrite="yes">
              <File Id="WEB.CONFIG" Name="web.config" Source="web.config" KeyPath="yes"/>
            </Component>
            <Component Id="SOMEFILE" DiskId="1" Guid="B835CEF5-1A84-4C37-8CB0-BE983BAF73F9">
              <File Id="SOMEFILE" Name="somefile.txt" Source="somefile.txt" KeyPath="yes"/>
              <util:XmlConfig Id="WEBCFG_1" File="[WebApp]Web.config" Action="create" Node="element" Name="module" ElementPath="/configuration/autofac/modules" VerifyPath="/configuration/autofac/modules/module[\[]@type='ICS.Automation.JDE.Base.JDEModule, ICS.Automation.JDE.Base'[\]]" Sequence="10" On ="install" />
              <util:XmlConfig Id="WEBCFG_2" ElementId="WEBCFG_1" File="[WebApp]Web.config" Name="type" Value="MyDll, MyDll" Sequence="11" />
            </Component>
          </Directory>
        </Directory>
      </Directory>
    </Directory>
  </Fragment>

  <Fragment>
    <ComponentGroup Id="ProductComponents">
      <ComponentRef Id="WEB.CONFIG"/>
    </ComponentGroup>
    <ComponentGroup Id="AdditionalComponents">
      <ComponentRef Id="SOMEFILE"/>
    </ComponentGroup>
  </Fragment>
</Wix>

如何在InstallFinalize之后更改RemoveExistingProducts?  最终,我只需要这个文件永远不会被覆盖。

谢谢!

1 个答案:

答案 0 :(得分:4)

MajorUpgrade标记是进行升级的首选方式,它将在您指定的任何地方对RemoveExistingProducts(REP)进行排序 - 这应该简化其中的一部分。用户界面没有理由移动REP。

调度REP的默认值是在InstallValidate之后,这基本上是对旧产品的卸载,然后安装升级,所以它不是一个更新/覆盖配置文件的卸载/删除后再进行全新安装。

如果REP安装在AfterInstallExecute之后,则在升级期间会应用覆盖规则(因为升级&#34;覆盖&#34;卸载之前的现有已安装产品)。 web.config文件只需要在旧产品和新产品中具有相同的组件ID,如果在安装后确实已经更改,则覆盖规则应该意味着它不会被覆盖。

https://msdn.microsoft.com/en-us/library/windows/desktop/aa370531(v=vs.85).aspx

换句话说,只需使用带有afterInstallExecute的主要升级元素,在旧资源和新资源(文件等)中都有相同的组件ID,并且web.config文件不应被覆盖,并且你不会被覆盖。需要设置neveroverwrite。

在我看来,使用REP afterInstallExecute比InstallFinalize更好,因为后者在安装事务之外,因此升级安装可以成功,然后InstallFinalize之后的REP可能会失败并回滚,同时安装两个产品。如果旧产品的卸载失败,则在事务中使用REP会导致完全回滚。