Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Inno Setup ExtractTemporaryFile causes wizard to freeze

I've made custom pages to manage specific redist tools install depending on the user choice.

Those tools are linked to checkboxes checked by the user if he wants or not install those tools. Then come a page only there to show the user the progression of the installation of each tool.

The issue I have here is that the progress page is shown only when first ExtractTemporaryFile of the setups for the tools is done, showing the last page as if it has frozen.

The only way I have to let the progress page be shown before the ExtractTemporaryFile happens is to put a MsgBox before any install function. But even in this case, when the ExtractTemporaryFile is launched, the progress bar animation is frozen until the ExtractTemporaryFile is done...

Here is the part of the code doing this:

procedure CurPageChanged(CurPageID: Integer);
begin
  If CurPageID=PageInstallationPersonnalisee.ID then
    begin
      ProgressBarLabelPageInstPerso.Caption := 'Initialisation...';
      if InstallTool1 = True then
        begin
          ProgressBarLabelPageInstPerso.Caption := 'Installing InstallTool1...';
          F_InstallTool1();
        end;
      if InstallTool2 = True then
        begin
          ProgressBarLabelPageInstPerso.Caption := 'Installing InstallTool2...';
          F_InstallTool2();
        end;
      if InstallTool3 = True then
        begin
          ProgressBarLabelPageInstPerso.Caption := 'Installing InstallTool3...';
          F_InstallTool3();
        end;

      ProgressBarPageInstPerso.Style := npbstMarquee;
      //ProgressBarPageInstPerso.Style := npbstNormal;
      ProgressBarPageInstPerso.Position := 100;

      CancelWithoutPrompt:=True;
      WizardForm.Close;
    end;
end;

Note that ExtractTemporaryFile() is made in each F_InstallTooln() function.

Others part of Setup and File Sections that could help:

[Setup]
SolidCompression=no

[Files]
;Temporary redists
Source: "{#MyRessourcesPath}InstallTool1_Setup.exe"; DestDir: "{tmp}"; \
  Flags: deleteafterinstall noencryption dontcopy
Source: "{#MyRessourcesPath}InstallTool2_Setup.exe"; DestDir: "{tmp}"; \
  Flags: deleteafterinstall noencryption dontcopy
Source: "{#MyRessourcesPath}InstallTool3_Setup.exe"; DestDir: "{tmp}"; \
  Flags: deleteafterinstall noencryption dontcopy

Here, the page PageInstallationPersonnalisee is not shown until first ExtractTemporaryFile is done...

I'm aware that ExtractTemporaryFile can cause some delay in install process, but why should it cause the wizard to freeze?

So my question is: in my scenario, is there a way to force the wizard refreshing so that he shows up before any ExtractTemporaryFile procedure is launched?

like image 481
BenDev Avatar asked Oct 17 '22 19:10

BenDev


2 Answers

The ExtractTemporaryFile really hangs the wizard form. As most code does.

The only custom page that allows forcing Windows message queue to get pumped is the TOutputProgressWizardPage (created by the CreateOutputProgressPage).

You can do something like this:

function NextButtonClick(CurPageID: Integer): Boolean;
var
  ProgressPage: TOutputProgressWizardPage;
begin
  if CurPageID = wpReady then
  begin
    ProgressPage := CreateOutputProgressPage('Preparing installations', '');
    ProgressPage.Show;
    try
      ProgressPage.Msg1Label.Caption := 'Installing 1 ...';
      ProgressPage.SetProgress(0, 100);
      ExtractTemporaryFile('1.exe');
      Exec(...);

      ProgressPage.Msg1Label.Caption := 'Installing 2 ...';
      ProgressPage.SetProgress(33, 100);
      ExtractTemporaryFile('2.exe');
      Exec(...);

      ProgressPage.Msg1Label.Caption := 'Installing 3 ...';
      ProgressPage.SetProgress(66, 100);
      ExtractTemporaryFile('3.exe');
      Exec(...);

      ProgressPage.SetProgress(100, 100);
      ProgressPage.Hide;
    finally
    end;
  end;
  Result := True;
end;

Though it does not work really well either on modern versions of Windows that have fancy progress bar with animation, if you cannot call the SetProgress frequently. Note that the SetProgress call is what does pump the message queue behind the scenes. So it makes sense to call it even when its parameter do not change. But you cannot, as the ExtractTemporaryFile blocks.


Alternatively, you can leave the deployment to the [Files] section and have the installers be executed from the AfterInstall event.

[Files]
;Temporary redists
Source: "{#MyRessourcesPath}InstallTool1_Setup.exe"; DestDir: "{tmp}"; \
  Flags: deleteafterinstall noencryption dontcopy; AfterInstall: Install1
Source: "{#MyRessourcesPath}InstallTool2_Setup.exe"; DestDir: "{tmp}"; \
  Flags: deleteafterinstall noencryption dontcopy; AfterInstall: Install2
Source: "{#MyRessourcesPath}InstallTool3_Setup.exe"; DestDir: "{tmp}"; \
  Flags: deleteafterinstall noencryption dontcopy; AfterInstall: Install3
like image 159
Martin Prikryl Avatar answered Oct 21 '22 01:10

Martin Prikryl


I know this is an old thread but I was facing a similar situation where some of the files I was extracting using the ExtractTemporaryFile function were significantly slower than the others.

After some investigation I found this on Inno Setup help pages:

When solid compression is enabled, be sure to list your temporary files at (or near) the top of the [Files] section. In order to extract an arbitrary file in a solid-compressed installation, Setup must first decompress all prior files (to a temporary buffer in memory). This can result in a substantial delay if a number of other files are listed above the specified file in the [Files] section.

This means that for optimal performance you should move the files that you want to extract using that function to the top of the [Files] section.

like image 33
Fedaykin Avatar answered Oct 21 '22 01:10

Fedaykin