Windows 安装程序在产品升级期间删除版本控制文件,而不是将其降级
我们使用 wix 来创建我们的设置。对于升级,我们使用主要升级,如 Rob Mensching 的回答< /a>. (在较新的 wix 版本中,您可以使用 MajorUpgrade 元素。)这通常效果很好。删除旧产品,然后安装新产品。
但是,显然上述并不完全等同于手动卸载旧产品然后手动安装新产品。
例如,考虑以下场景:
- 我们产品的版本 1.0 发布,包含第三方 dll 的版本 5.0
- 我们产品的版本 1.1 发布,包含同一第三方 dll 的版本 5.1
- 我们产品的版本 1.2 发布,降级到版本 5.0再次使用第三方dll,因为我们发现新版本引入的问题多于它解决的问题。
显然,根据上面链接的 wix 升级逻辑,从版本 1.1 升级到 1.2 时,3rdparty dll 将消失。需要进行修复才能恢复它。
是否有另一种升级方法适用于这种情况?我想我正在寻找的是升级逻辑,它允许组件降级,其行为就像手动卸载旧产品然后手动安装新产品一样。
We use wix to create our setups. For upgrading, we use major upgrades as demonstrated in this answer by Rob Mensching. (In newer wix versions you can use the MajorUpgrade element.) This normally works well. The old product is removed, then the new product is installed.
However, apparently the above is not completely equivalent to manually uninstalling the old product and then manually installing the new product.
Consider for example the following scenario:
- version 1.0 of our product is released, containing version 5.0 of a thirdparty dll
- version 1.1 of our product is released, containing version 5.1 of the same thirdparty dll
- version 1.2 of our product is released, downgrading to version 5.0 of the thirdparty dll again because we discovered that the new version introduced more problems than it solved.
Apparently with the wix upgrade logic linked above, the 3rdparty dll will disappear when upgrading from release 1.1 to 1.2. A repair is necessary to restore it.
Is there another way to upgrade, which would work for this scenario? I guess what I am looking for is upgrade logic which allows the downgrading of components, by behaving exactly as if one manually uninstalls the old product and then manually installs the new product.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(6)
我们还遇到了这个问题,即在重大升级时未重新安装较低版本的 DLL。我觉得很奇怪的是,安装程序会根据现有文件的版本控制来决定安装哪些文件,然后完全卸载所有内容,但仍然只安装之前确定要安装的文件卸载旧产品。这看起来可能是 Windows Installer 中的错误...
为了解决此问题,我们将
RemoveExistingProducts
操作移至CostFinalize
操作上方。我了解MSDN 上的文档建议将
RemoveExistingProducts
afterInstallValidate
,我不确定将其放在InstallValidate
操作之前是否会对次要升级产生任何负面影响,但我们有决定只对我们的产品进行重大升级,因此该解决方案似乎适合我们。We also encountered this problem where lower-versioned DLLs were not getting reinstalled on a major upgrade. I thought it was strange that the installer would decide which files to install based on the versioning of existing files, then completely uninstall everything, but still only install what what files had been determined to install before uninstalling the old product. This seems like it might be a bug in Windows Installer...
To fix this problem we moved the
RemoveExistingProducts
action above theCostFinalize
action.I know the documentation on MSDN recommends placing the
RemoveExistingProducts
afterInstallValidate
, and I'm not sure if putting it before theInstallValidate
action has any negative side effects for minor upgrades, but we have decided to only perform major upgrades for our products so this solution appears to work for us.此类行为通常与 RemoveExistingProducts 的排序有关。如果发生得足够晚,Windows Installer 将发现计算机上有较新版本的 .dll,因此不需要安装 1.2 版。然而,当RemoveExistingProducts导致删除.dll时,没有任何东西可以将其恢复。
可以尝试的事情包括更改RemoveExistingProducts的顺序,以及谎报1.2包中的.dll版本(报告比错误版本号更高的版本号)。后者的缺点是对修复或修补影响不大,因为 .dll 看起来总是过时的。
Behaviors like this generally have to do with the sequencing of RemoveExistingProducts. If it occurs late enough, Windows Installer will have figured out that there's a newer version of the .dll on the machine, so version 1.2 doesn't need to install it. However when the RemoveExistingProducts results in removing the .dll, nothing puts it back.
Things to try including changing the sequencing of RemoveExistingProducts, and lying about the version of the .dll in your 1.2 package (report a version number higher than the bad one). The downside of the latter is poor impacts on repairs or patching, as the .dll always looks out of date.
尝试提前安排
RemoveExistingProducts
,对吧在InstallValidate
之后,更改的值将 REINSTALLMODE
属性设置为amus
。这样,在复制新产品中的任何文件之前,旧产品将被完全删除,并且a
模式将强制重新安装这些文件。Try to schedule
RemoveExistingProducts
earlier, right afterInstallValidate
, and change the value ofREINSTALLMODE
property toamus
. This way the old product will be completely removed before any files from the new product are copied, anda
mode will force re-install of the files.多年后,这条线索帮助我走向了正确的方向。在成本计算之前移动
RemoveExisitingProducts
的完整性示例:Years later, this thread helped me in the right direction. An example for completeness with
RemoveExisitingProducts
moved before costing:这是次优的,但我通过重命名第三方 dll 并更改 .wxs 文件中与其关联的组件节点上的 GUID 解决了同样的问题。
It's sub-optimal, but I fixed the same problem by renaming the third party dll and changing the GUID on the component node associated with it in the .wxs file.
这是我基于@Spacemani给出的答案的最终解决方案。
它生成与此类似的 MSI 表条目(升级、LaunchCondition 等),
但使您可以完全控制 InstallExecuteSequence。
请注意,您需要像这样抑制 .wixproj 文件中的 ICE27 错误。
Here's my final solution based on the answer given by @Spacemani.
It produces MSI table entries (Upgrade, LaunchCondition etc.) similar to this
but gives you full control of the InstallExecuteSequence.
Note that you need to suppress ICE27 errors in your .wixproj file like this.