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

如何在Wix3构建的MSI安装程序中关联自定义动作与进度条?

解决Wix 3中C++自定义动作关联进度条的问题

我之前也踩过Wix 3里C++自定义动作进度条不更新的坑,折腾了好一阵才理顺,给你分享下关键步骤和避坑点:

1. 确认自定义动作的执行类型

只有**延迟执行(Deferred)**的自定义动作才能在安装过程中更新进度条——即时(Immediate)动作是在序列早期执行的,这时候进度条还没进入激活状态,发送的进度消息根本不会被处理。

在Wix的XML里定义自定义动作时,一定要加上Execute="deferred"和Impersonate="no"(延迟动作通常需要系统权限):

<CustomAction Id="MyCppCustomAction" BinaryKey="MyCppBinary" DllEntry="MyCustomActionFunc" Execute="deferred" Impersonate="no" />

同时要把它放在InstallExecuteSequence的正确位置:在InstallInitialize之后,InstallFinalize之前:

<InstallExecuteSequence>
    <Custom Action="MyCppCustomAction" After="InstallInitialize">NOT Installed</Custom>
</InstallExecuteSequence>

2. 正确调用WcaProgressMessage

首先要确保你的自定义动作代码里初始化了WCA框架——开头调用WcaInitialize,结尾调用WcaFinalize,否则WcaProgressMessage会失效:

UINT __stdcall MyCustomActionFunc(MSIHANDLE hInstall) {
    UINT uiRetVal = ERROR_SUCCESS;
    HRESULT hr = S_OK;

    // 初始化WCA
    hr = WcaInitialize(hInstall, "MyCustomActionFunc");
    ExitOnFailure(hr, "Failed to initialize WCA");

    // --- 你的任务逻辑开始 ---
    UINT totalSteps = 10; // 根据实际任务拆分步骤数
    for (UINT i = 0; i < totalSteps; i++) {
        // 执行单个任务步骤
        DoYourTask(i);

        // 计算当前绝对进度百分比
        DWORD progress = (i + 1) * 100 / totalSteps;

        // 发送进度更新消息
        // 参数:消息类型(MESSAGE_ACTIONDATA)、是否增量更新(FALSE=绝对进度)、进度值
        hr = WcaProgressMessage(MESSAGE_ACTIONDATA, FALSE, progress);
        if (FAILED(hr)) {
            WcaLog(LOGMSG_ERROR, "Failed to send progress message: 0x%x", hr);
            goto LExit;
        }
    }
    // --- 你的任务逻辑结束 ---

LExit:
    uiRetVal = SUCCEEDED(hr) ? ERROR_SUCCESS : ERROR_INSTALL_FAILURE;
    WcaFinalize(uiRetVal);
    return uiRetVal;
}

这里要注意:

  • 如果你的任务是增量式的(比如每次完成固定比例的工作),可以把第二个参数设为TRUE,第三个参数传增量值(比如每次加10)。
  • 一定要用WcaLog记录错误,方便后续排查。

3. 配置进度文本

给自定义动作添加ProgressText,这样安装程序会在进度条上方显示当前动作的描述,同时也能确保进度系统正确关联这个动作:

<ProgressText Action="MyCppCustomAction">正在执行自定义任务,请稍候...</ProgressText>

4. 常见排查要点

  • 检查安装日志:用msiexec /i YourInstaller.msi /l*v install.log生成详细日志,搜索WcaProgressMessage看有没有错误返回码,或者进度消息是否被正确发送。
  • 确认自定义动作没有被跳过:检查序列里的条件(比如NOT Installed只在首次安装执行,如果是升级/修复要调整条件)。
  • 不要在即时动作里尝试更新进度:即时动作阶段进度条还没开始运转,所有进度消息都会被忽略。

内容的提问来源于stack exchange,提问作者Victor Hugo

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.07 13:32:45