如何防止 Wix Major 升级期间数据库丢失
How to prevent database drop during Wix Major upgrade
我正在使用 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 的回答,更改主要升级的顺序或计划是通过更改计划属性来完成的:
<MajorUpgrade
DowngradeErrorMessage="A newer version of [ProductName] is already installed."
Schedule="afterInstallExecute"/>
注意 然而,这只会带你到此为止 - 如果你计划在你的安装程序中添加对可信身份验证以及 SQL 身份验证的支持(根据上面的 SO 文章)它不会工作,我的假设是 Wix 确定一个组件从未安装(无论未选择哪个身份验证选项),因此将始终删除数据库。
有几种方法可以解决这个问题,具体取决于 MSI 的内部结构:
在 InstallExecute 之后和 InstallFinalize 之前在 "end" 排序的主要升级意味着升级基本上是在当前安装的产品之上安装新产品.文件覆盖规则适用,其中之一是如果数据文件在安装后已更新,则不会被替换。这样数据文件就保存下来了。其他注意事项是必须为需要更新的二进制文件版本更新,并且必须遵循组件规则。
如果问题是基于 运行 卸载旧产品时的自定义操作,那么您可以使用自定义操作条件,例如 REMOVE="ALL" 和不升级产品代码。 UPGRADINGPRODUCTCODE 是在卸载旧产品时设置的,而不是在传入升级中设置的。
我相信某些 WiX util 类型的自定义操作是基于相关组件的卸载,因此您在 2 中不需要该条件。InstallExecute 后的重大升级增加了每个组件的引用计数组件(这就是为什么您需要遵循组件规则),同时遵循文件覆盖规则。因此,您的数据文件会将其引用计数计数为 2,不会被覆盖,然后较旧的产品卸载会将其计数为 1,以便组件保留,并且基于组件删除的卸载自定义操作不会 运行。
如果您需要在基于自定义操作的升级安装中执行某些操作,那么 WIX_UPGRADE_DETECTED 会告诉您您正在升级已安装的产品。
关于您提到的升级 link,Chris Painter 的回答是正确的。这基本上与我在这里提出的观点相同,所以他当然是正确的:)
我正在使用 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 的回答,更改主要升级的顺序或计划是通过更改计划属性来完成的:
<MajorUpgrade
DowngradeErrorMessage="A newer version of [ProductName] is already installed."
Schedule="afterInstallExecute"/>
注意 然而,这只会带你到此为止 - 如果你计划在你的安装程序中添加对可信身份验证以及 SQL 身份验证的支持(根据上面的 SO 文章)它不会工作,我的假设是 Wix 确定一个组件从未安装(无论未选择哪个身份验证选项),因此将始终删除数据库。
有几种方法可以解决这个问题,具体取决于 MSI 的内部结构:
在 InstallExecute 之后和 InstallFinalize 之前在 "end" 排序的主要升级意味着升级基本上是在当前安装的产品之上安装新产品.文件覆盖规则适用,其中之一是如果数据文件在安装后已更新,则不会被替换。这样数据文件就保存下来了。其他注意事项是必须为需要更新的二进制文件版本更新,并且必须遵循组件规则。
如果问题是基于 运行 卸载旧产品时的自定义操作,那么您可以使用自定义操作条件,例如 REMOVE="ALL" 和不升级产品代码。 UPGRADINGPRODUCTCODE 是在卸载旧产品时设置的,而不是在传入升级中设置的。
我相信某些 WiX util 类型的自定义操作是基于相关组件的卸载,因此您在 2 中不需要该条件。InstallExecute 后的重大升级增加了每个组件的引用计数组件(这就是为什么您需要遵循组件规则),同时遵循文件覆盖规则。因此,您的数据文件会将其引用计数计数为 2,不会被覆盖,然后较旧的产品卸载会将其计数为 1,以便组件保留,并且基于组件删除的卸载自定义操作不会 运行。
如果您需要在基于自定义操作的升级安装中执行某些操作,那么 WIX_UPGRADE_DETECTED 会告诉您您正在升级已安装的产品。
关于您提到的升级 link,Chris Painter 的回答是正确的。这基本上与我在这里提出的观点相同,所以他当然是正确的:)