You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

重大升级回滚场景下,如何在RemoveExistingProduct后启动服务?

问题背景

现有安装程序的自定义操作序列:
InstallInitialize(标准操作)→RemoveExistingProduct(标准操作)→若干自定义操作→StartService(标准操作)

在重大升级过程中,若StartService执行前触发回滚,RemoveExistingProduct会执行。操作完成后,应用服务已通过自定义操作启用,但未启动。

已尝试的方案及问题:

  • 编写回滚自定义操作Rollback_startService,按「InstallInitialize→Rollback_startservice→RemoveExistingProduct」调度时,RemoveExistingProduct标准操作抛出“序列错误”报错;
  • StartService标准操作不会在RemoveExistingProduct标准操作流程中被调用;
  • 安装程序多处使用UPGRADINGPRODUCTCODE属性,无法调整RemoveExistingProduct的调度位置。

需求:需通过StartService标准操作或Rollback_startService自定义操作启动服务,求最优解决方案。

最优解决方案

核心思路

利用MSI回滚序列的绑定规则,将Rollback_startService自定义操作与原StartService标准操作的回滚逻辑关联,同时通过精准条件限制,确保仅在重大升级回滚且服务已启用未启动的场景下触发,规避序列冲突问题。

具体步骤

  1. 定义Rollback_startService自定义操作

    • 操作类型设为19(msidbCustomActionTypeRollback + msidbCustomActionTypeInScript),标记为脚本化回滚操作,符合MSI序列执行规范。
    • 操作逻辑:检查目标服务的启动类型与运行状态,若服务已启用(注册表Start值为2/3)但未运行,则调用系统API启动服务。
  2. 配置调度与执行条件

    • 将Rollback_startService放置在InstallInitialize之后、RemoveExistingProduct之前,添加执行条件:
      REMOVE="ALL" AND UPGRADINGPRODUCTCODE AND SERVICE_START_TYPE="2" OR SERVICE_START_TYPE="3"
      
      (注:SERVICE_START_TYPE需提前通过自定义操作查询服务注册表项获取并存入属性)
    • 该条件确保仅在重大升级回滚、且服务已启用的场景下触发操作,避免干扰正常安装流程。
  3. 关联原StartService的回滚逻辑

    • 为原StartService标准操作指定回滚自定义操作为Rollback_startService,确保当StartService被回滚触发时,自动调用该自定义操作。

关键注意点

  • 保留RemoveExistingProduct的原调度位置,兼容现有UPGRADINGPRODUCTCODE的多处使用;
  • 脚本化回滚操作类型可避免“序列错误”,符合MSI的执行顺序规则;
  • 精准的条件判断可防止操作在非目标场景下执行,避免引发新的安装问题。

内容的提问来源于stack exchange,提问作者user-24

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.18 07:55:23