如何在 Wix 主要升级期间防止数据库丢失

Posted

技术标签:

【中文标题】如何在 Wix 主要升级期间防止数据库丢失【英文标题】:How to prevent database drop during Wix Major upgrade 【发布时间】:2016-01-12 12:34:44 【问题描述】:

我正在使用 Wix 3.10 构建一个安装程序,它将安装文件、创建服务以及创建和填充数据库。

我正在使用 Wix sql:SqlDatabase 元素创建数据库并在安装期间运行一些 sql 脚本来填充它(主要基于 WIX database deployment, installation)

按照 Wix 文档中的建议,我正在测试一个模拟升级,然后再发布初始安装程序。据我所知,强烈建议坚持重大升级,因此我按照示例使用MajorUpgrade 元素。

不幸的是,在重大升级期间,我似乎无法阻止 Wix 卸载数据库,也找不到任何有关如何处理此问题的指导。我知道重大升级实际上是卸载当前版本,然后重新安装新版本,但肯定有办法保留原始版本的一部分吗?

我安装的服务也有类似的问题,但基于这个 SO 问题Wix Major Upgrade: how do I prevent Windows service reinstallation?,解决方案似乎是在安装序列的删除服务条目中添加一个条件:

<InstallExecuteSequence>
    <DeleteServices>NOT UPGRADINGPRODUCTCODE</DeleteServices>
</InstallExecuteSequence>

暗示对我来说,可以在重大升级中保留条目,但我可能会误解。

不幸的是,SqlDatabase 实体似乎没有任何等效的 installexecute 序列元素。有没有关于如何处理这个问题的指导?

更新

根据PhilDW的回答,更改主要升级的顺序或时间表是通过更改Schedule属性来完成的:

<MajorUpgrade 
  DowngradeErrorMessage="A newer version of [ProductName] is already installed."
  Schedule="afterInstallExecute"/>

注意但是,这只会带您到此为止 - 如果您计划在安装程序中添加对可信身份验证和 SQL 身份验证的支持(根据上面的 SO 文章),它将不起作用,我的假设是 Wix 确定从未安装过一个组件(未选择任何身份验证选项),因此将始终删除数据库。

【问题讨论】:

【参考方案1】:

有几种方法可以解决这个问题,具体取决于您的 MSI 的内部结构:

    在“结束”排序的主要升级,在 InstallExecute 之后和 InstallFinalize 之前,意味着升级基本上是在当前安装的产品之上安装新产品。文件覆盖规则适用,其中之一是如果数据文件在安装后已更新,则不会被替换。因此数据文件被保存。其他注意事项是必须为需要更新的二进制文件版本更新,并且必须遵循组件规则。

    如果问题是基于在卸载旧产品时运行的自定义操作,那么您可以使用自定义操作条件,例如 REMOVE="ALL" 而不是 UPGRADINGPRODUCTCODE。 UPGRADINGPRODUCTCODE 是在旧产品被卸载时设置的,而不是在即将到来的升级中设置的。

    我相信某些 WiX util 类型的自定义操作基于相关组件的卸载,因此您在 2 中不需要该条件。InstallExecute 之后的重大升级会增加每个组件的引用计数(即为什么需要遵循组件规则)同时遵循文件覆盖规则。因此,您的数据文件的引用计数最多为 2,不会被覆盖,然后较旧的产品卸载会将其计数为 1,以便组件保留,并且基于组件删除的卸载自定义操作将不会运行。

    如果您在升级安装中需要做一些基于自定义操作的操作,那么 WIX_UPGRADE_DETECTED 会告诉您正在升级已安装的产品。

在您所指的升级链接上,Chris Painter 的回答是正确的。这基本上与我在这里提出的观点相同,所以他当然是正确的:)

【讨论】:

以上是关于如何在 Wix 主要升级期间防止数据库丢失的主要内容,如果未能解决你的问题,请参考以下文章

如何防止 wix 自定义引导程序卸载 UI 在升级过程中显示

C# 如何防止在长时间运行的查询期间因崩溃而丢失数据?

在 WIX 升级期间重新启动 Windows 服务

卸载升级时如何摆脱wix中未使用的dll

Wix - 在安装/升级期间,自定义操作的条件在不应该的情况下解析为False

如何使用 WIX 升级数据库?