InstallShield大版本升级未完全卸载旧版本问题咨询
你遇到的这个问题非常典型——Major Upgrade确实不会默认触发旧版本中的InstallScript卸载代码,核心原因在于Windows Installer的Major Upgrade机制本身的工作方式:它主要是基于MSI数据库中的组件、注册表等信息来移除旧产品,不会自动执行旧版安装包中自定义的InstallScript卸载逻辑,除非你主动配置相关选项或者手动触发。
下面是具体的解决步骤:
检查旧版InstallScript动作的配置
首先确认旧版本的InstallScript卸载逻辑(比如OnUninstall函数或者相关自定义动作)是否被正确添加到了旧版MSI的卸载序列中。如果旧版的InstallScript代码只是写在了脚本里,但没有关联到卸载事件的自定义动作,那即使是手动卸载旧版也不会执行,更别说Major Upgrade了。启用Major Upgrade的“使用旧版卸载序列”选项
在InstallShield 2016的Major Upgrade视图中,找到你创建的升级条目,勾选**“卸载旧版本时使用其卸载序列”**(英文对应选项:Use the uninstall sequence of the old product when removing it)。这个选项会告诉Windows Installer在卸载旧产品时,完整执行旧版MSI中定义的卸载流程,包括其中的InstallScript自定义动作。手动触发旧版的完整卸载流程
如果上面的选项没有生效,或者旧版的InstallScript逻辑没有集成到MSI卸载序列中,可以在新版本的InstallScript中主动调用旧版的卸载命令:- 先通过MSI API(比如
MsiEnumProducts)找到旧版本的产品代码 - 在新版本的
OnFirstUIBefore或者OnInstalling事件中,调用LaunchApp执行msiexec /x {旧产品代码} /qn,这样会完整触发旧版的卸载流程,包括所有InstallScript卸载逻辑 - 注意要确保旧版卸载完成后再继续新版本的安装,可以通过等待进程结束的逻辑来实现
- 先通过MSI API(比如
排查自定义动作的运行条件
检查旧版的InstallScript自定义动作是否设置了限制条件,比如是否只允许在交互式卸载时运行(而Major Upgrade默认是静默卸载)。如果是这种情况,要么修改旧版的动作条件,要么在调用旧版卸载时加上/qb参数来启用基本交互,确保条件满足。通过日志定位问题
生成详细的MSI安装日志(运行msiexec /i 你的新版安装包.msi /l*v install.log),在日志中搜索旧产品代码相关的卸载记录,查看是否有跳过InstallScript动作的提示,或者有没有错误代码,这能帮你精准定位问题所在。
内容的提问来源于stack exchange,提问作者agshah

