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

Inno Setup下载页显示文件计数及选中组件统计实现方法

问题描述

假设正在使用官方示例CodeDownloadFiles.iss,希望向用户提示下载状态,显示*“第N个/共Y个文件”*形式的下载进度计数。

最初的思路是先获取选中组件的总数,但不知道如何修改下载页上*“Downloading additional files...”*的提示标签。尝试直接给类属性赋值失败,错误写法如下:

TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 1 of 3, please wait...'

当前已编写的代码尚未实现选中组件总数的获取逻辑,不确定是否可以通过自定义函数遍历校验组件选中状态实现统计,现有代码如下:

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  //Download Components
  if CurPageID = wpReady then begin
    DownloadPage.Clear;

    if WizardIsComponentSelected('Database\ABC') then begin
      TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 1 of 3, please wait...'
      DownloadPage.Add('https://example.com/MyDB1.sqlite', 'MyDB1.sqlite', '');
    end;
    if WizardIsComponentSelected('Database\DEF') then begin
      TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 2 of 3, please wait...'
      DownloadPage.Add('https://example.com/MyDB2.sqlite', 'MyDB2.sqlite', '');;
    end;
    if WizardIsComponentSelected('Database\GHI') then begin
      TDownloadWizardPage.DownloadingLabel := 'Downloading additional files... file 3 of 3, please wait...'
      DownloadPage.Add('https://example.com/MyDB3.sqlite', 'MyDB3.sqlite', '');;
    end;
    DownloadPage.Show;
    try
      try
        DownloadPage.Download;
        Result := True;
      except
        SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
        Result := False;
      end;
    finally
      DownloadPage.Hide;
    end;
  end else
  Result := True;
end;

核心诉求:

  • 解决下载页提示标签修改失败的问题,实现动态显示「当前下载文件序号/总文件数」的效果
  • 找到程序化统计选中组件对应待下载文件总数量的实现方法

解决方案

1. 标签修改失败的原因

TDownloadWizardPage是类类型,不是实例对象,直接给类的属性赋值是无效的。你创建的DownloadPage才是页面实例,而且DownloadingLabel本质是实例上的TLabel控件,需要修改它的Caption属性才能生效。
另外原有写法是在添加文件的时候就修改标签,但下载过程是批量执行的,标签不会在每个文件下载开始时自动切换,需要绑定下载进度回调来实时更新。

2. 统计逻辑说明

不需要单独遍历组件统计总数,在给DownloadPage添加下载项的时候同步计数即可,逻辑更准确——毕竟未选中的组件不会添加下载任务,计数结果和实际要下载的文件数完全一致。如果确实需要单独统计选中组件数量,可以遍历WizardForm.ComponentsList条目判断选中状态实现。

3. 完整可运行实现代码

[Code]
var
  DownloadPage: TDownloadWizardPage;
  TotalDownloadFiles: Integer;

// 下载进度回调,实时更新标签
procedure OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64);
var
  CurrentFileIndex: Integer;
begin
  // 匹配当前正在下载的文件序号
  for CurrentFileIndex := 0 to DownloadPage.ItemCount - 1 do
  begin
    if DownloadPage.ItemURL[CurrentFileIndex] = Url then
    begin
      // 序号从1开始计算
      DownloadPage.DownloadingLabel.Caption := Format('Downloading additional files... file %d of %d, please wait...', [CurrentFileIndex + 1, TotalDownloadFiles]);
      Break;
    end;
  end;
end;

procedure InitializeWizard();
begin
  DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress);
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  if CurPageID = wpReady then begin
    DownloadPage.Clear;
    TotalDownloadFiles := 0;

    // 逐个判断组件选中状态,添加下载项,同步计数
    if WizardIsComponentSelected('Database\ABC') then begin
      DownloadPage.Add('https://example.com/MyDB1.sqlite', 'MyDB1.sqlite', '');
      TotalDownloadFiles := TotalDownloadFiles + 1;
    end;
    if WizardIsComponentSelected('Database\DEF') then begin
      DownloadPage.Add('https://example.com/MyDB2.sqlite', 'MyDB2.sqlite', '');
      TotalDownloadFiles := TotalDownloadFiles + 1;
    end;
    if WizardIsComponentSelected('Database\GHI') then begin
      DownloadPage.Add('https://example.com/MyDB3.sqlite', 'MyDB3.sqlite', '');
      TotalDownloadFiles := TotalDownloadFiles + 1;
    end;

    // 无需要下载的文件直接跳过
    if TotalDownloadFiles = 0 then begin
      Result := True;
      Exit;
    end;

    // 初始化标签为第一个文件的状态
    DownloadPage.DownloadingLabel.Caption := Format('Downloading additional files... file 1 of %d, please wait...', [TotalDownloadFiles]);
    
    DownloadPage.Show;
    try
      try
        DownloadPage.Download;
        Result := True;
      except
        SuppressibleMsgBox(AddPeriod(GetExceptionMessage), mbCriticalError, MB_OK, IDOK);
        Result := False;
      end;
    finally
      DownloadPage.Hide;
    end;
  end else
    Result := True;
end;

补充说明

如果需要单独统计选中组件的数量(而非待下载文件数),可以用如下自定义函数实现:

function GetSelectedComponentCount: Integer;
var
  i: Integer;
begin
  Result := 0;
  for i := 0 to WizardForm.ComponentsList.Items.Count - 1 do
  begin
    if WizardForm.ComponentsList.Checked[i] then
      Result := Result + 1;
  end;
end;

如果存在父组件和子组件联动选中的情况,上述组件计数函数会把父子条目都算入统计,如果需要过滤父级条目,根据组件层级增加判断逻辑即可。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.01 21:27:38