如何在WixSharp中配置升级,避免提前删旧文件且保留固定ProductId?
我刚加入新团队,接手一款跨平台后台代理应用的多端安装程序,其中Windows端基于WixSharp 1.9.3(WiX 3)和.NET 4.5.1构建MSI。这个代理是静默后台运行的,负责按后端IT要求应用补丁和配置,一旦安装失败,IT会失去设备控制权,只能手动重装。
我对Windows平台、.NET、Installer API、WiX及WixSharp了解有限,查了一周文档还是没解决问题。
从安装日志看,RemoveFiles操作会在安装初期运行,先删除旧版本再装新版本,导致设备出现无代理的真空期,严重影响可恢复性。
为提升可恢复性,我们修改了安装流程:
- 将新版本二进制文件安装为
agent-{newVersion}.exe - 在PostInstall脚本中执行以下步骤:
- 对
agent-{newVersion}.exe做兼容性和功能测试,失败则终止流程 - 将现有
agent.exe复制为agent-{oldVersion}.exe - 将
agent-{newVersion}.exe复制为agent.exe(覆盖旧版本)
- 对
但这个方案存在漏洞:因为要兼容全新安装场景(旧文件不存在),脚本无法检测到旧文件已被提前删除。测试中如果在PostInstall测试阶段重启设备,恢复后没有agent.exe,服务无法启动,必须手动重新运行安装程序。
后续尝试
我尝试调整MajorUpgrade的执行时机,代码如下:
project.MajorUpgrade = new MajorUpgrade { Schedule = UpgradeSchedule.afterInstallExecute, };
这把RemoveExistingProducts(推测是RemoveFiles的父操作)移到了流程后期——完成自测并替换agent.exe之后。此时如果安装中途意外重启,旧版本还能正常运行,可恢复性有所提升,但新问题出现:后续RemoveExistingProducts仍会运行,删除agent.exe,导致安装完成后二进制文件缺失。
我尝试直接抑制这个操作,添加了以下XML配置:
<InstallExecuteSequence> <RemoveExistingProducts Suppress="yes"/> </InstallExecuteSequence>
但得到错误:
The InstallExecuteSequence table contains an action 'RemoveExistingProducts' that cannot be suppressed because it is not declared overridable in the base definition. Please stop suppressing the action or make it overridable in its base declaration.
查相关问题得知,RemoveExistingProducts是MajorUpgrade的核心操作,不建议抑制。
另外,我知道可以用新ProductId执行普通安装替代MajorUpgrade,但客户有产品ID白名单限制,不能随版本变更ProductId。
核心诉求
Wix和WixSharp的选型及MajorUpgrade的使用都是之前团队确定的,相关人员已离职,现在必须保留Windows Installer及MSI文件。
请问有没有替代MajorUpgrade的方案,或者调整现有配置的方法,能实现不在写入新文件前删除旧二进制文件,同时保证卸载时能删除agent.exe及所有agent-{version}.exe文件?
内容的提问来源于stack exchange,提问作者JakeRobb

