1

我们使用 wix 3.9 为我们的产品创建一个 msi。我们的目标:我们希望通过 msi 提供一个配置文件(.txt 文件)。当安装文件夹中已存在配置文件时,该文件不应被升级覆盖。不幸的是,在升级时,Wix 会删除配置文件。

产品元素:

<Product Id="*" Name="$(var.AppName) V$(var.Version) $(var.TargetBuild)" Language="1033" Version="$(var.Version)" Manufacturer="$(var.Manufacturer)" UpgradeCode="$(var.UpgradeCode)">

是静态的$(var.UpgradeCode),永远不会改变。

升级标签:

<MajorUpgrade DowngradeErrorMessage="A newer version of $(var.AppName) is already installed." AllowSameVersionUpgrades="yes" />

<Upgrade Id="$(var.UpgradeCode)">
  <UpgradeVersion Minimum="1.0.0"
                  IncludeMinimum="yes"
                  OnlyDetect="yes"
                  Maximum="$(var.Version)"
                  IncludeMaximum="yes" 
                  Property="PREVIOUSVERSIONSINSTALLED" />
</Upgrade>

<Property Id="PREVIOUSVERSIONSINSTALLED" Secure="yes" />

这是配置文件:

<Component Id="ConfigComponent" NeverOverwrite="yes" Guid="GUID-HERE">
    <File Id="ConfigOutput" KeyPath="yes" Name="MyConfig.config" Source="MyConfig.config.bak"/>
</Component>

此外,我使用RemoveFolderEx来删除应用程序本身生成的文件。但是当我注释掉这个块时,问题仍然存在。但我想显示代码块的完整性:

<Component Id="RemoveAll" Guid="MYGUID">
    <RemoveFile Id="RemoveAllFilesOnUninstall" Directory="APPLICATIONFOLDER" Name="*.*" On="uninstall" />
    <RemoveFolder Id="RemoveAllFoldersOnUninstall" Directory="APPLICATIONFOLDER" On="uninstall" />

    <RegistryValue Root="HKLM" Key="SOFTWARE\$(var.Manufacturer)\$(var.AppName)" Name="Path" Type="string" Value="[APPLICATIONFOLDER]" KeyPath="yes" />
    <util:RemoveFolderEx On="uninstall" Property="APPLICATIONFOLDER" /> 
</Component>

Repro:首先,我们安装软件,“MyConfig.config”文件按预期出现在应用程序文件夹中。之后,我们在此配置文件中进行更改。接下来,我们构建第二个 .msi 并执行它。进行更新时,所有文件都会按预期覆盖。但是我们现在在安装文件夹中缺少文件“MyConfig.config”。

更新:

该属性Permanent="yes"也无法按预期工作。配置文件在升级时仍然被删除:

<Component Id="ConfigComponent" Permanent="yes" NeverOverwrite="yes" Guid="GUID-HERE">
    <File Id="ConfigOutput" KeyPath="yes" Name="MyConfig.config" Source="MyConfig.config.bak"/>
</Component>
4

1 回答 1

2

重大升级期间发生的情况:

  1. CostInitialize/CostFinalize 操作确定应安装新 MSI 中的哪些组件。ConfigComponent 决定“不”安装,因为它被标记为 NeverOverwrite="yes"。
  2. 旧的 MSI 在 RemoveExistingProducts 操作期间被删除。之前的配置文件被删除。
  3. 新的 MSI 已安装。根据步骤 1 的检查,未安装 ConfigComponent。

一个快速的解决方案(尽管我确信那里有更好的方法):

接下来,将您的 ConfigComponent 标记为 Permanent="yes",这样 MSI 就不会删除它。您需要添加删除文件的自定义操作,并将其设置为“$ConfigComponent=2 And Not UPGRADINGPRODUCTCODE”,以便仅在将组件设置为通过修改或完全卸载删除时执行,但不执行升级。

如果您的 MSI 已经发布到世界各地,并且您需要修复升级方案,您需要编写一个自定义操作,在旧 MSI 删除之前将配置文件复制到备份位置。然后另一个自定义操作将配置文件复制回正确的目录。

于 2016-04-04T15:49:11.567 回答