downloadinno-setuppascalscript

How to display real-time download speed in Inno Setup's TDownloadWizardPage?


I'm trying to add download speed (in MB/s/KB/s) display to Inno Setup's download page.
I've been using the IDP for over a decade, but finally I wanted to migrate to the built-in file download functionality, unfortunately I was a bit disappointed because you have to program everything yourself, there's nothing like IDP that shows a nice download page with the number of files, download speed, etc. I wanted to start with something simple and at least show the download speed of the current file, I tried a few suggestions from AI but, like AI, it doesn't always do the right thing, so I gave up, and came here to ask for help.

This is my current code:

[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;

Calling it with

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

Solution

  • Update your OnDownloadProgress to calculate the speed based on Progress and elapsed time.

    Something like this:

    function GetTickCount64: Int64; external 'GetTickCount64@kernel32 stdcall';
      
    var
      DownloadStart: Int64;
    
    function OnDownloadProgress(
      const Url, FileName: String; const Progress, ProgressMax: Int64): Boolean;
    var
      Elapsed: Int64;
      Kbs: Integer;
      Msg1: string;
    begin
      Elapsed := (GetTickCount64 - DownloadStart);
      Msg1 := SetupMessage(msgDownloadingLabel);
      if Elapsed >= 3 then
      begin
        Kbs := Integer((Progress div 1024 * 1000) div Elapsed);
        Msg1 := Msg1 + Format(' (%d KB/s)', [Kbs]);
      end;
      DownloadPage.Msg1Label.Caption := Msg1;
    
      if Progress = ProgressMax then
        Log(Format('Successfully downloaded file to {tmp}: %s', [FileName]));
      Result := True;
    end;
    

    Initialize DownloadStart before DownloadPage.Download:

          DownloadStart := GetTickCount64;
          DownloadPage.Download;
    

    enter image description here