Search code examples
installationinno-setupfreezepascalscript

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?


Solution

  • 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