Wix Toolset UpgradeVersion关联属性重置与自定义动作执行异常排查
核心问题定位
你猜测的OLDVERSIONFOUND被中途重置的情况确实存在,这就是两个动作配置了相同执行条件,却出现一个正常执行、一个被跳过的核心原因,和Windows Installer对升级流程的内置处理逻辑直接相关,两个动作的条件写法本身没有问题。
实际执行流程和你预想的顺序完全错位:
- 安装流程走到
InstallValidate阶段后,系统会自动执行FindRelatedProducts动作检测匹配升级规则的旧版本,成功匹配后就会给OLDVERSIONFOUND属性赋值 - 紧接着触发你定义的
BackupFiles动作,此时OLDVERSIONFOUND还保留着检测到的旧版本版本号,条件满足,动作正常执行 - 流程推进到
InstallInitialize阶段后,会立刻触发你配置的RemoveExistingProducts动作,把检测到的旧版本完全卸载 - 旧版本卸载完成的同时,Windows Installer会自动清空
FindRelatedProducts生成的OLDVERSIONFOUND属性——系统默认判断旧版本已经被移除,这个标记旧版本存在的临时属性已经没有保留意义 - 等流程走到
InstallFiles完成、要触发RestoreFiles动作的时候,OLDVERSIONFOUND已经是空值,条件不满足,因此被跳过,日志输出条件为假的提示
代码中存在的其他问题
- 你定义的
<Property Id="RestoreFiles" Value="INSTALL_FOLDER" />和自定义动作RestoreFiles重名,后续动作执行时很容易出现路径取值错误、属性被意外覆盖的问题,建议把属性重命名为RestoreFilePath这类和动作名不冲突的标识 - 当前配置的
SetRestoreFiles动作没有定义对应的脚本/DLL入口,也没有绑定执行逻辑,属于无效配置,不会正常生效 - Upgrade节点的
Maximum="0.0.0.0"配置不符合常规升级逻辑,会导致所有低于当前产品版本的已安装程序都被识别为待升级的旧版本,甚至可能出现误覆盖更高版本产品的问题
可行修复方案
- 如果你要保持“备份旧文件→安装新文件→恢复备份文件→清理旧版本残留”的逻辑,直接把
RemoveExistingProducts的执行时机从After="InstallInitialize"调整到After="RestoreFiles",让旧版本卸载流程放到所有自定义文件操作完成之后,此时OLDVERSIONFOUND会一直保留属性值直到所有自定义动作执行完毕,不会被提前清空 - 如果一定要保留
RemoveExistingProducts在InstallInitialize之后的位置,就需要在BackupFiles动作执行时手动把OLDVERSIONFOUND的值读取出来,写入到一个不会被系统自动清空的持久自定义属性中,后续RestoreFiles的执行条件改成判断这个自定义属性,而不是直接依赖系统自动生成的OLDVERSIONFOUND
内容的提问来源于stack exchange,提问作者dgxhubbard
相关产品推荐
相关产品推荐

