如何在回滚场景中检测旧版本Bundle触发的MsiA重装?
解决WiX 4 Bundle回滚时依赖服务无法自动启动的问题
问题背景
- 基于WiX 4 Bundle部署三个MSI包(MsiA、MsiB、MsiC),所有MSI通过
MajorUpgrade配置升级,Schedule="afterInstallInitialize" - MsiA安装Windows服务
MsiAService;MsiB安装依赖MsiAService的MsiBService;MsiC不含服务 - Bundle按顺序安装各MSI,服务通过
ServiceInstall、ServiceDependency、ServiceControl完成配置
回滚异常流程
- MsiB升级失败触发回滚,回滚完成后启动
MsiBService - 旧版本Bundle执行MsiA重装操作:停止
MsiAService,导致依赖的MsiBService被强制关闭 - MsiA回滚完成后重新启动
MsiAService - 核心问题:
MsiBService始终处于停止状态,WiX无内置机制自动启动该依赖服务
现有尝试的问题
已在MsiA中编写自定义动作Tools.ExecuteServiceCommand,但配置的条件<Custom Action="Tools.ExecuteServiceCommand" After="StartServices" Condition="WIX_UPGRADE_DETECTED" />无法触发,需准确识别「回滚场景下由旧版本Bundle触发的重装」状态
解决方案
1. 组合MSI内置属性检测目标场景
通过多个MSI内置属性的组合,精准匹配回滚+重装的场景:
ROLLBACK:标记当前处于回滚流程WIX_UPGRADE_DETECTED:检测到升级操作REMOVE="ALL":旧版本正在执行卸载(重装的核心环节)
修改自定义动作条件为:
<Custom Action="Tools.ExecuteServiceCommand" After="StartServices" Condition="ROLLBACK AND WIX_UPGRADE_DETECTED AND REMOVE="ALL"" />
2. 通过Bundle传递自定义回滚标记
如果MSI内置属性的组合检测不够精准,可在Bundle中为MsiA传递自定义属性,明确标记回滚场景:
<Chain> <MsiPackage SourceFile="MsiA.msi" Id="MsiA"> <MsiProperty Name="BUNDLE_IS_ROLLBACK" Value="[WIX_ROLLBACK_DETECTED]" /> </MsiPackage> <!-- 其他MsiPackage配置 --> </Chain>
随后在MsiA中基于该自定义属性配置条件:
<Custom Action="Tools.ExecuteServiceCommand" After="StartServices" Condition="BUNDLE_IS_ROLLBACK="1" AND WIX_UPGRADE_DETECTED" />
3. 自定义动作内直接检查并启动服务
若属性检测仍有边界问题,可在Tools.ExecuteServiceCommand自定义动作内部跳过属性判断,直接检查MsiBService状态:
- 使用Windows API(
OpenService、QueryServiceStatus、StartService)或PowerShell命令(Get-Service MsiBService/Start-Service MsiBService),检测服务是否停止,若停止则启动它
内容的提问来源于stack exchange,提问作者ManuHArt
相关产品推荐
相关产品推荐

