Inno Setup - Copy Files with Progress Bar on a custom page

Viewed 450

I'm currently working on a program that updates our companys software.

I'm letting a User chose the location of the installed program and a backup location in an "CreateInputDirPage"

Currently I'm creating a mask for the selection of the two directorys:

SelectPathPage := CreateInputDirPage(PreviousPageId, 'Text 1', 'Text 2.', 'Text 3', False, 'New Folder'); SelectPathPage.Add('Path to company program'); SelectPathPage.Add('Path to backup folder');

Then I'm validating with existing files if the first Folder indead holds our companys program. Now I want to copy the first selection to a new subfolder in the Backup-Folder.

I found this sample code from another question for copying the files: DirectoryCopy(SelectPathPage.Values[0], SelectPathPage.Values[1]);

Which seems to work with the "NextButtonClick"-Function.

How can I copy the folder and the content of the folder on a seperate mask after the "SelectPathPage"-Mask with a progress bar and making the next button available when the copy is finished. It should be similar to the "Install"-Mask with the progress bar. Is it even possible to create something like this in a custom mask in Inno Setup?

Thanks in Advance

1 Answers

Use CreateOutputProgressPage to create the progress page.

And modify the DirectoryCopy function from Copying hidden files in Inno Setup to advance the progress on the page.

To calculate the total size (to set the maximum of the progress bar), the code needs GetDirSize function from Inno Setup get directory size including subdirectories.

[Code]

const
  ProgressRatio = 1024;

procedure DirectoryCopyWithProgress(
  SourcePath, DestPath: string; ProgressPage: TOutputProgressWizardPage);
var
  FindRec: TFindRec;
  SourceFilePath: string;
  DestFilePath: string;
  Size: Int64;
begin
  if FindFirst(SourcePath + '\*', FindRec) then
  begin
    try
      repeat
        if (FindRec.Name <> '.') and (FindRec.Name <> '..') then
        begin
          SourceFilePath := SourcePath + '\' + FindRec.Name;
          DestFilePath := DestPath + '\' + FindRec.Name;
          ProgressPage.SetText(SourceFilePath, DestFilePath);
          if FindRec.Attributes and FILE_ATTRIBUTE_DIRECTORY = 0 then
          begin
            Size := Int64(FindRec.SizeHigh) shl 32 + FindRec.SizeLow;
            if FileCopy(SourceFilePath, DestFilePath, False) then
            begin
              Log(Format('Copied %s to %s with %s bytes', [
                SourceFilePath, DestFilePath, IntToStr(Size)]));
            end
              else
            begin
              Log(Format('Failed to copy %s to %s', [
                SourceFilePath, DestFilePath]));
            end;
          end
            else
          begin
            Size := 0;
            if DirExists(DestFilePath) or CreateDir(DestFilePath) then
            begin
              Log(Format('Created %s', [DestFilePath]));
              DirectoryCopyWithProgress(
                SourceFilePath, DestFilePath, ProgressPage);
            end
              else
            begin
              Log(Format('Failed to create %s', [DestFilePath]));
            end;
          end;

          Size := Size / ProgressRatio;
          ProgressPage.SetProgress(
            ProgressPage.ProgressBar.Position + Longint(Size),
            ProgressPage.ProgressBar.Max);
        end;
      until not FindNext(FindRec);
    finally
      FindClose(FindRec);
    end;
  end
    else
  begin
    Log(Format('Failed to list %s', [SourcePath]));
  end;
end;

function SelectPathPageNextButtonClick(Sender: TWizardPage): Boolean;
var
  SourcePath: string;
  DestPath: string;
  ProgressPage: TOutputProgressWizardPage;
  TotalSize: Longint;
begin
  ProgressPage := CreateOutputProgressPage('Copying files...', '');
  SourcePath := TInputDirWizardPage(Sender).Values[0];
  DestPath := TInputDirWizardPage(Sender).Values[1];
  TotalSize := GetDirSize(SourcePath) / ProgressRatio;
  Log(Format('Total size is %s', [IntToStr(TotalSize)]));
  ProgressPage.SetProgress(0, TotalSize);
  ProgressPage.Show;
  try
    DirectoryCopyWithProgress(SourcePath, DestPath, ProgressPage);
  finally
    ProgressPage.Hide;
    ProgressPage.Free;
  end;
  Result := True;
end;

procedure InitializeWizard();
var
  SelectPathPage: TInputDirWizardPage;
begin
  SelectPathPage :=
    CreateInputDirPage(
      wpSelectDir, 'Text 1', 'Text 2.', 'Text 3', False, 'New Folder');
  SelectPathPage.Add('Path to company program');
  SelectPathPage.Add('Path to backup folder');
  SelectPathPage.OnNextButtonClick := @SelectPathPageNextButtonClick;
end;

enter image description here

enter image description here

Related