InstallScript执行应用主升级时如何获取旧版本应用的安装路径
InstallShield主升级场景下动态获取旧版本安装路径的问题排查
现有开发状态
- 目标是优化安装程序实现主升级(Major Upgrade)能力,通过自定义操作调用InstallScript函数,完成应用安装目录下部分文件的备份与恢复逻辑
- 硬编码旧版本安装目录的场景下,整套备份恢复流程可正常运行
- 调用
MsiGetProductInfo接口传入当前版本产品代码PRODUCT_GUID时,可正常获取当前版本安装路径,对应代码:MsiGetProductInfo(PRODUCT_GUID, INSTALLPROPERTY_INSTALLLOCATION, savedInstallDir, bufferSize); - 异常场景:将接口入参替换为硬编码的旧版本产品代码值后,
savedInstallDir始终返回空字符串,对应代码片段:MsiGetProductInfo("{my-previous-product-code}", INSTALLPROPERTY_INSTALLLOCATION, savedInstallDir, bufferSize);
核心问题原因与落地解决方法
- 严格校验旧版本产品代码的匹配性
Windows Installer的ProductCode是大小写严格匹配的唯一标识,传入的旧版本代码必须和旧版本安装时写入系统缓存的ProductCode完全一致——包括大括号格式、连字符分隔规则、字符大小写,任意一处不匹配都会被判定为无效产品,接口直接返回空值。 - 调整自定义操作的执行时机
主升级流程中,Windows Installer会在较早的执行节点触发旧版本卸载流程。如果读取旧版本路径的自定义操作绑定在InstallValidate阶段之后执行,旧版本的注册表缓存信息会被提前清除,此时调用接口自然无法获取到有效路径。正确执行时机:将读取旧版本安装路径的InstallScript自定义操作,绑定在
InstallInitialize阶段之前的用户界面序列节点执行,确保此时旧版本的缓存信息未被卸载流程篡改、清除。 - 适配
INSTALLPROPERTY_INSTALLLOCATION的天生特性
该属性对应Windows Installer缓存的“应用安装位置”字段,只有当旧版本安装包主动将ARPINSTALLLOCATION项写入系统注册表时,该字段才会有有效值。如果旧版本安装包从未设置过这个属性,哪怕传入的产品代码完全正确,该属性的返回值本身就是空的。替代取值方案:针对未配置
ARPINSTALLLOCATION的旧版本,直接读取系统注册表中应用卸载项下对应产品的DisplayIcon、InstallSource字段,解析得到真实安装路径,不要硬依赖INSTALLPROPERTY_INSTALLLOCATION属性。 - 校验自定义操作的执行权限
读取全局安装的旧版本产品信息时,如果自定义操作以普通用户权限执行,不具备系统注册表对应项的读取权限,也会导致接口返回空值。需要将自定义操作的执行上下文设置为msidbCustomActionTypeNoImpersonate,匹配系统安装权限等级执行。
内容的提问来源于stack exchange,提问作者t c
相关产品推荐
相关产品推荐

