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

WiX Toolset v3.11能否在Bootstrapper进度页添加双进度条?

实现WiX Bootstrapper双进度条(整体+单个包)

完全可以实现双进度条的需求,具体操作分为以下两个核心步骤:

1. 修改主题文件添加单个包进度控件

在RtfLargeTheme.xml的Progress页面中,新增单个包进度的文本标签和进度条,调整布局避免与原有控件重叠:

<Page Name="Progress">
    <Text X="11" Y="80" Width="-11" Height="30" FontId="2" DisablePrefix="yes">#(loc.ProgressHeader)</Text>
    <!-- 整体进度区域 -->
    <Text X="11" Y="121" Width="70" Height="17" FontId="3" DisablePrefix="yes">整体进度:</Text>
    <Text Name="OverallProgressPackageText" X="85" Y="121" Width="-11" Height="17" FontId="3" DisablePrefix="yes">#(loc.OverallProgressPackageText)</Text>
    <Progressbar Name="OverallCalculatedProgressbar" X="11" Y="143" Width="-11" Height="15" />
    <!-- 单个包进度区域 -->
    <Text X="11" Y="170" Width="70" Height="17" FontId="3" DisablePrefix="yes">当前包进度:</Text>
    <Text Name="CurrentPackageText" X="85" Y="170" Width="-11" Height="17" FontId="3" DisablePrefix="yes">准备安装...</Text>
    <Progressbar Name="CurrentPackageProgressbar" X="11" Y="192" Width="-11" Height="15" />
    <Button Name="ProgressCancelButton" X="-11" Y="-11" Width="75" Height="23" TabStop="yes" FontId="0">#(loc.ProgressCancelButton)</Button>
</Page>

2. 自定义Bootstrapper Application监听进度事件

WiX v3.11的默认BA不会自动更新单个包的进度,需要自定义BA来捕获包的安装事件并更新控件:

步骤1:创建自定义BA类库

新建C#类库项目,引用Microsoft.Tools.WindowsInstallerXml.Bootstrapper程序集,实现进度监听逻辑:

using Microsoft.Tools.WindowsInstallerXml.Bootstrapper;

public class CustomBA : BootstrapperApplication
{
    protected override void Run()
    {
        Engine.Detect();
        Engine.Plan(LaunchAction.Install);

        // 绑定进度相关事件
        Engine.PackageStarted += OnPackageStarted;
        Engine.PackageProgress += OnPackageProgress;

        // 启动UI循环(根据你使用的UI框架调整,如WinForms/WPF)
        // 示例:如果用WinForms,这里启动主窗体循环
        // Application.Run(new ProgressForm(this));
    }

    private void OnPackageStarted(object sender, PackageStartedEventArgs e)
    {
        // 根据PackageId获取对应显示名称,更新UI文本
        string displayName = GetPackageDisplayName(e.PackageId);
        UpdateCurrentPackageText(displayName);
    }

    private void OnPackageProgress(object sender, PackageProgressEventArgs e)
    {
        // WiX传递的Progress值范围是0-1000,转换为0-100的百分比
        int progressPercent = e.Progress / 10;
        UpdateCurrentPackageProgress(progressPercent);
    }

    // 以下方法需根据实际UI实现补充
    private string GetPackageDisplayName(string packageId)
    {
        // 可从Bundle的本地化资源或预定义映射中获取名称
        return packageId switch
        {
            "DesktopNet50Runtime" => ".NET 5.0 桌面运行时",
            "AVS" => "AVS主程序",
            "DockerDesktop" => "Docker Desktop",
            "AVS_OtherFiles" => "AVS附加资源",
            "DockerEngine" => "Docker引擎",
            _ => "未知组件"
        };
    }

    private void UpdateCurrentPackageText(string text)
    {
        // 更新CurrentPackageText控件的显示内容
        // 示例:如果用WinForms,找到对应Label控件赋值
    }

    private void UpdateCurrentPackageProgress(int percent)
    {
        // 更新CurrentPackageProgressbar控件的进度值
        // 示例:如果用WinForms,设置ProgressBar的Value属性
    }
}

步骤2:在Bundle中指定自定义BA

修改Bundle.wxs,配置使用自定义BA:

<Bundle ...>
    <BootstrapperApplicationRef Id="ManagedBootstrapperApplicationHost">
        <Payload SourceFile="你的自定义BA.dll路径" />
        <Payload SourceFile="Microsoft.Tools.WindowsInstallerXml.Bootstrapper.dll" />
    </BootstrapperApplicationRef>
    <!-- 原有Chain定义 -->
    <Chain>
        <PackageGroupRef Id="DesktopNet50Runtime" />
        <PackageGroupRef Id="AVS" />
        <PackageGroupRef Id="DockerDesktop"/>
        <PackageGroupRef Id="AVS_OtherFiles" After="DockerDesktop"/>
        <PackageGroupRef Id="DockerEngine" After="AVS_OtherFiles"/>
    </Chain>
</Bundle>

关键注意点

  • 对于无进度反馈的.exe包(如部分第三方安装程序),WiX无法获取其内部进度,此时可以添加模拟进度动画,或仅在包开始/结束时更新状态提示。
  • 所有文本建议通过本地化资源文件管理,保持与原有主题的一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.05 23:15:27