InstallShield 2020 InstallScript转MSI的安装升级及旧版接管问题咨询
旧InstallScript安装包MSI接管与标准化升级实现方案
前置规则配置
- 提前提取所有历史InstallScript安装包的特征值:包括写入的注册表路径、默认安装目录、版本号存储位置、核心组件清单,用于后续旧安装识别,旧包未遵循MSI规范无ProductCode/UpgradeCode,只能通过自定义特征检测
- 按三类组件要求配置MSI组件属性:
- 卸载可移除的基础组件:对应所有Component的
Permanent属性设为no,默认纳入卸载清理范围 - 卸载不可移除的复杂组件:对应所有Component的
Permanent属性设为yes,卸载时自动跳过 - 用户可选移除的数据库类组件:对应Component绑定自定义控制属性,卸载时根据用户选择触发对应的清理脚本
- 卸载可移除的基础组件:对应所有Component的
- 按场景配置UpgradeCode规则:主产品使用固定UpgradeCode用于大版本升级识别,小版本补丁复用同ProductCode仅迭代版本号,独立复杂组件可单独分配UpgradeCode实现按需升级
旧安装接管核心逻辑
核心思路是在MSI标准检测流程前插入自定义识别逻辑,确认旧安装存在且完整后,直接关联现有资源,不覆盖原有文件
- 在MSI的
InstallUISequence和InstallExecuteSequence的FindRelatedProducts动作前,插入自定义检测动作(可使用VBScript/C#自定义动作实现):检测逻辑参考: 1. 读取历史InstallScript包写入的注册表项,确认产品已安装 2. 校验安装目录存在且核心组件完整、版本符合升级要求 3. 检测通过后设置自定义属性`OLDPRODUCT_EXISTS=1`,并将旧安装路径赋值给MSI的`INSTALLDIR`属性 - 所有文件类Component的
NeverOverwrite属性设为yes,当OLDPRODUCT_EXISTS=1时,MSI只会校验资源存在性,不会覆盖现有文件,同时自动将现有文件关联到对应Component的键路径,纳入MSI资源管理体系 - 调整
RemoveExistingProducts动作的触发时机到InstallFinalize之后,且仅在检测到同UpgradeCode的MSI历史版本时触发,历史InstallScript安装的版本不需要执行卸载逻辑,避免误删现有文件
多升级场景适配
- 重大升级(Major Upgrade):
升级包使用新的ProductCode、沿用主产品固定UpgradeCode,版本号至少提升主版本/次版本号一位,检测逻辑验证旧安装(含InstallScript旧版本)版本≥最低兼容要求、组件完整后,仅更新有版本变更的Feature/Component,执行数据库重大升级脚本 - 小版本升级/补丁(Minor Upgrade):
升级包沿用原有ProductCode,仅迭代内部版本号,检测逻辑验证旧安装版本为指定兼容版本后,仅执行数据库小幅升级脚本,不修改Feature/Component结构,不覆盖用户自定义配置
卸载一致性保证
接管完成后所有资源均已绑定到MSI的Component规则,卸载时MSI会自动按照预设的Permanent属性、用户选择的清理选项执行对应操作,表现和原生MSI从零安装的产品完全一致
内容的提问来源于stack exchange,提问作者LiberyBell
相关产品推荐
相关产品推荐

