实现Wix配套文件的正确方法?

实现Wix配套文件的正确方法?,wix,windows-installer,wix3,Wix,Windows Installer,Wix3,我们目前正在将构建脚本从3.0升级到3.5,并在此过程中修复一系列旧的ICE错误。我已经阅读了许多文章,但对于使用配套文件的最佳方法,我有点困惑 现在,假设文件A.manifest是A.exe的伴随文件 最初:我们的旧版本将2个文件分解为2个组件: <Component Guid="*" Id="A.exe" SharedDllRefCount="yes"> <File Id="..." KeyPath="yes" Source="A.exe"/> </Co

我们目前正在将构建脚本从3.0升级到3.5,并在此过程中修复一系列旧的ICE错误。我已经阅读了许多文章,但对于使用配套文件的最佳方法,我有点困惑

现在,假设文件A.manifest是A.exe的伴随文件

最初:我们的旧版本将2个文件分解为2个组件:

<Component Guid="*" Id="A.exe" SharedDllRefCount="yes">
    <File Id="..." KeyPath="yes" Source="A.exe"/>
</Component>
<Component Guid="*" Id="A.exe.manifest" SharedDllRefCount="yes">
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>
<Component Guid="*" Id="A.exe" SharedDllRefCount="yes"> <!-- GUID is wrong! -->
    <File Id="..." KeyPath="yes" Source="A.exe"/>
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>

这会触发ICE54:警告组件“A.exe.manifest”使用文件“A.exe.manifest”作为其密钥路径,但该文件的版本由文件“A.exe”提供,因此我猜它显然是错误的

第一种方法:因此我尝试将KeyPath=yes添加到同伴的目录中:

<Component .../>
<Component Guid="*" Id="A.exe.manifest" SharedDllRefCount="yes" KeyPath="yes">
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>

这会抑制警告,但在Orca中,组件的KeyPath列显示为空白,因此我怀疑它是否正确

第二种方法:接下来,我尝试组合组件:

<Component Guid="*" Id="A.exe" SharedDllRefCount="yes">
    <File Id="..." KeyPath="yes" Source="A.exe"/>
</Component>
<Component Guid="*" Id="A.exe.manifest" SharedDllRefCount="yes">
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>
<Component Guid="*" Id="A.exe" SharedDllRefCount="yes"> <!-- GUID is wrong! -->
    <File Id="..." KeyPath="yes" Source="A.exe"/>
    <File CompanionFile="A.exe" Id="..." Source="A.exe.manifest"/>
</Component>

但是,允许WiX在这里自动生成guid似乎是行不通的。但是如果我手动生成guid,那么每次构建它时,升级时都会打破组件规则!实际上,我们部署了很多配套文件,因此生成每个组件的哈希并永久存储它也可能是不可行的。对于每个压缩文件使用虚拟注册表项,同上


TLDR:在WiX中,这两种方法中哪一种实际上是更好的实践?

我的问题是,在这样做时,您试图解决什么问题?一般来说,除非您对组件规则和使用/不使用配套文件的服务含义有非常深入的了解,否则您可能应该坚持组件与文件的比例为1:1,其中所有文件都是关键文件。这不是一个绝对的规则,但它可能是95-99%的最佳值


也就是说,看看File元素上的KeyPath属性,记住当一个组件在MSI的KeyPath列中没有数据时,这意味着组件目录就是密钥路径。

Hmm,我认为通常最好将未版本/未版本文件设置为DLL或EXE的伴随文件,这样,在升级/卸载过程中,可以正确添加或删除配套文件-是这样吗?我也知道Windows Installer能够处理带有修改时间和MsiFileHash的未版本文件,但我们以前从未尝试过。这个功能足够可靠吗?是的,它很可靠。这取决于您希望对该文件执行什么操作。作为附带文件,当keyfile更新时,所有文件都会更新。由于它是自己的密钥文件,修改时间决定了决策。如果用户/进程在安装文件后对其进行了调整,该怎么办?你想在下一次升级时对这些调整进行重击,还是想让它们单独存在,不再复制文件?啊,除了少数文件外,几乎所有这些文件实际上都安装在程序文件和公共文件中,因此用户永远不会修改它们。有了这个,我想最好按照你的建议让它们成为自己的密钥文件。2.但是根据“文件版本控制规则”,如果一个未版本的文件在之后被修改,它永远不会被覆盖,那么假设它是自己的密钥文件,我如何强制它这样做?搜索“wix版本”。基本上,这是一种黑客行为,你告诉MSI你的文件有一个版本,即使它没有。这会改变行为。InstallShield将此文件级别称为“始终覆盖”。这绕过了一个事实,即仅在包级别强制重新安装模式amus/omus。另一种方法是使用伴随路径,这样当DLL get更新时,TXT文件get就会更新。不幸的是,Windows Installer就是这样设计的。它试图保护“用户数据”,但在XML文件之类的东西中不理解这一点。