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

如何在Inno Setup的TDownloadWizardPage中显示实时下载速度?

在Inno Setup内置下载页面添加下载速度显示功能

我使用IDP已有十余年,如今想要迁移至Inno Setup内置文件下载功能,但该功能需要自行编写逻辑,没有IDP那样的美观下载页面(支持显示文件数量、下载速度等)。我希望至少实现当前文件的下载速度(MB/s/KB/s)显示功能,尝试过一些方案但效果不佳,求助解决。

当前代码如下:

[Code]
var
  DownloadPage: TDownloadWizardPage;

function OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean;
begin
  if Progress = ProgressMax then
    Log(Format('Successfully downloaded file to {tmp}: %s', [FileName]));
  Result := True;
end;

procedure InitializeWizard;
var
  WelcomePage: TWizardPage;
begin
  DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress);
  DownloadPage.ShowBaseNameInsteadOfUrl := False;

  Server_URL := 'https://myinternetpage.com/';
end;

function MyDownload(BaseName, RequiredSHA256OfFile: String): Boolean;
var
  Retry: Boolean;
  Answer: Integer;
  ErrorMessage: String;
  ExceptionMessage: String;
begin
  repeat
    try
      DownloadPage.Clear;
      DownloadPage.Add(Server_URL + BaseName, BaseName, RequiredSHA256OfFile);
      DownloadPage.Download;
      Retry := False;
      Result := True;
    except
      if DownloadPage.AbortedByUser then
      begin
        Log('Aborted by user.');
        Result := False;
        Retry := False;
      end
      else
      begin
        ExceptionMessage := GetExceptionMessage;
        ErrorMessage := 'Error downloading file: ' + #13#10 + #13#10 + BaseName + #13#10 + #13#10 + AddPeriod(ExceptionMessage);
        Log(ErrorMessage);
        DownloadPage.Msg2Label.Caption := Server_URL + BaseName;

        if (Pos('12029', ExceptionMessage) > 0) or (Pos('12007', ExceptionMessage) > 0) then
        begin
          MsgBox('No internet connection - download skipped: ' + BaseName, mbInformation, MB_OK);
          Retry := False;
          Result := False;
        end
        else
        begin
          Answer := SuppressibleMsgBox(ErrorMessage, mbCriticalError, MB_ABORTRETRYIGNORE, IDABORT);
          Retry := (Answer = IDRETRY);
          Result := (Answer <> IDABORT);
        end;
      end;
    end;
  until not Retry;
end;

调用代码:

MyDownload('Filename.zip', '');

解决方案

要实现下载速度显示,需要跟踪下载的时间和字节变化,计算实时速度并更新下载页面的UI。以下是修改后的完整代码:

[Code]
var
  DownloadPage: TDownloadWizardPage;
  // 新增变量用于计算下载速度
  LastProgress: Int64;
  LastTime: DWORD;
  SpeedLabel: TLabel;

function FormatFileSize(Size: Int64): String;
var
  KB, MB: Double;
begin
  KB := Size / 1024;
  MB := KB / 1024;
  if MB >= 1 then
    Result := Format('%.2f MB/s', [MB])
  else if KB >= 1 then
    Result := Format('%.2f KB/s', [KB])
  else
    Result := Format('%d B/s', [Size]);
end;

function OnDownloadProgress(const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean;
var
  CurrentTime: DWORD;
  Elapsed: Double;
  BytesDelta: Int64;
begin
  if Progress = 0 then
  begin
    // 下载开始时初始化变量
    LastProgress := 0;
    LastTime := GetTickCount;
    SpeedLabel.Caption := '速度: 0 B/s';
  end
  else
  begin
    CurrentTime := GetTickCount;
    Elapsed := (CurrentTime - LastTime) / 1000; // 转换为秒
    if Elapsed >= 0.5 then // 每0.5秒更新一次速度,避免频繁刷新
    begin
      BytesDelta := Progress - LastProgress;
      if BytesDelta > 0 then
      begin
        SpeedLabel.Caption := '速度: ' + FormatFileSize(Round(BytesDelta / Elapsed));
      end;
      // 更新上次记录的进度和时间
      LastProgress := Progress;
      LastTime := CurrentTime;
    end;
  end;

  if Progress = ProgressMax then
  begin
    Log(Format('Successfully downloaded file to {tmp}: %s', [FileName]));
    SpeedLabel.Caption := '速度: 完成';
  end;
  Result := True;
end;

procedure InitializeWizard;
var
  WelcomePage: TWizardPage;
begin
  DownloadPage := CreateDownloadPage(SetupMessage(msgWizardPreparing), SetupMessage(msgPreparingDesc), @OnDownloadProgress);
  DownloadPage.ShowBaseNameInsteadOfUrl := False;

  // 创建速度显示标签并添加到下载页面
  SpeedLabel := TLabel.Create(WizardForm);
  SpeedLabel.Parent := DownloadPage.Surface;
  SpeedLabel.Left := DownloadPage.ProgressBar.Left;
  SpeedLabel.Top := DownloadPage.ProgressBar.Top + DownloadPage.ProgressBar.Height + 8;
  SpeedLabel.Caption := '速度: 等待下载...';

  Server_URL := 'https://myinternetpage.com/';
end;

function MyDownload(BaseName, RequiredSHA256OfFile: String): Boolean;
var
  Retry: Boolean;
  Answer: Integer;
  ErrorMessage: String;
  ExceptionMessage: String;
begin
  repeat
    try
      DownloadPage.Clear;
      DownloadPage.Add(Server_URL + BaseName, BaseName, RequiredSHA256OfFile);
      // 重置速度计算变量
      LastProgress := 0;
      LastTime := 0;
      SpeedLabel.Caption := '速度: 开始下载...';
      DownloadPage.Download;
      Retry := False;
      Result := True;
    except
      if DownloadPage.AbortedByUser then
      begin
        Log('Aborted by user.');
        Result := False;
        Retry := False;
        SpeedLabel.Caption := '速度: 已取消';
      end
      else
      begin
        ExceptionMessage := GetExceptionMessage;
        ErrorMessage := 'Error downloading file: ' + #13#10 + #13#10 + BaseName + #13#10 + #13#10 + AddPeriod(ExceptionMessage);
        Log(ErrorMessage);
        DownloadPage.Msg2Label.Caption := Server_URL + BaseName;
        SpeedLabel.Caption := '速度: 下载出错';

        if (Pos('12029', ExceptionMessage) > 0) or (Pos('12007', ExceptionMessage) > 0) then
        begin
          MsgBox('无网络连接 - 已跳过下载: ' + BaseName, mbInformation, MB_OK);
          Retry := False;
          Result := False;
        end
        else
        begin
          Answer := SuppressibleMsgBox(ErrorMessage, mbCriticalError, MB_ABORTRETRYIGNORE, IDABORT);
          Retry := (Answer = IDRETRY);
          Result := (Answer <> IDABORT);
        end;
      end;
    end;
  until not Retry;
end;

关键修改说明

  • 新增LastProgress、LastTime变量,记录上一次的下载进度和时间戳,用于计算速度变化
  • 添加SpeedLabel标签,嵌入到下载页面中显示实时速度
  • 实现FormatFileSize函数,根据字节数自动转换为合适的速度单位(B/s、KB/s、MB/s)
  • 在OnDownloadProgress事件中,每0.5秒计算一次下载速度并更新标签,避免UI频繁刷新
  • 在MyDownload函数中,处理下载开始、取消、出错等状态下的标签显示,同时重置速度计算变量

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.13 15:24:50