如何在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
相关产品推荐
相关产品推荐

