5

I use Inno Setup for many "standard" installers, but for this task I need to extract a bunch of temp files, run one of them, then remove them and exit the installer (without actually installing anything).

Basically I'm looking to make a self-extractor with without it being an "installer", and am after the best user experience possible with inno setup.

I have the following code which almost works fine:

[Files]
Source: "dist\*"; Flags: recursesubdirs ignoreversion dontcopy;
[Code]
function InitializeSetup(): Boolean;
var
  ResultCode: Integer;
begin
  Result := True;
  MsgBox('Please wait a minute or two...', mbInformation, MB_OK);
  ExtractTemporaryFiles('{tmp}\*');
  Exec(ExpandConstant('{tmp}\MyScript.exe'), '', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  Abort();
end;

The problem is that the best I can do here is show a message box "Please wait a minute or two...", the user clicks [Ok], then waits as nothing appears to happen with nothing on-screen at all, then MyScript.exe starts.

What I'd like instead is a Wizard page saying "Please wait as temporary files are extracted..." with a npbstMarquee style progress bar, then is disappears once the files are extracted and my script starts.

I don't think there's a way to tell Inno Setup to display a progress bar while ExtractTemporaryFiles() is going (which would be ideal) and working this into a custom wizard page has got me baffled.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Zuur
  • 101
  • 1
  • 6

2 Answers2

6
  • "Install" the files to {tmp}, instead of using ExtractTemporaryFiles;
  • Execute the files extracted to {tmp} from Run section (or use AfterInstall parameter or CurStepChanged to trigger Pascal Script code after files are installed);
  • Set Uninstallable to no;
  • Set CreateAppDir to no;
  • Use [Messages] section to edit the wizard texts that are too installer-centric for your needs.
[Setup]
Uninstallable=no
CreateAppDir=no

[Files]
Source: "dist\*"; DestDir: {tmp}; Flags: recursesubdirs

[Run]
FileName: "{tmp}\MyScript.exe"

Notes:

  • The {tmp} folder gets automatically deleted, when the "installer" is closing;
  • No need for ignoreversion flag, when installing to new empty folder.

A related question: Inno Setup installer that only runs a set of embedded installers


For an answer your literal question, see Inno setup: ExtractTemporaryFile causes wizard freeze. Or a more generic question on the topic: Inno Setup: How to modify long running script so it will not freeze GUI?

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
  • 2
    terrific answer; very clean responsive user experience and very simple script. [Messages] section can be used to adjust all text as needed. – Zuur Aug 28 '18 at 03:53
0

It seems that ExtractTemporaryFiles() essentially locks up the UI until it's finished, so there's no way to get a progress bar (or Marquee) animated in here.

Also getting a message on the screen at all while ExtractTemporaryFiles() is in progress was difficult. I solved it like this:

const
  WM_SYSCOMMAND = 274;
  SC_MINIMIZE = $F020;
//-------------------------------------------------------------------
procedure MinimizeButtonClick();
begin
  PostMessage(WizardForm.Handle, WM_SYSCOMMAND, SC_MINIMIZE, 0);
end;
//-------------------------------------------------------------------
procedure CurPageChanged(CurPageID: Integer);
var
  ResultCode: Integer;
begin
  if CurPageID = wpPreparing then
  begin
    MinimizeButtonClick();
    Exec(ExpandConstant('{tmp}\MyScript.exe'), '', '', SW_HIDE, ewWaitUntilTerminated, ResultCode);
  end;
end;
//-------------------------------------------------------------------
function NextButtonClick(CurPageID: Integer): Boolean;
var
  ProgressPage: TOutputProgressWizardPage;
begin
  if CurPageID = wpReady then
  begin
    ProgressPage := CreateOutputProgressPage('Preparing files...', '');
    ProgressPage.Show;
    try
      ProgressPage.Msg1Label.Caption := 'This process can take several minutes; please wait ...';
      ExtractTemporaryFiles('{tmp}\*');
    finally
      ProgressPage.Hide;
    end;
  end;
  Result := True;
end;
//-------------------------------------------------------------------
procedure CurStepChanged(CurStep: TSetupStep);
begin
  if CurStep = ssInstall then
  begin
    //MinimizeButtonClick() is called here as the Wizard flashes up for a second
    // and minimizing it makes that 1/2 a second instead...
    MinimizeButtonClick();
    Abort();
  end;
end;

I then changed the text on the "Ready" page to suit using the [Messages] section.

The result is:

  • one wizard page asking the user if they want to continue
  • one wizard page telling the user "please wait..." while the temp files are extracted
  • once the files are extracted the wizard is hidden and MyScript.exe from the temp folder is run
  • once MyScript.exe finishes the wizard exits cleanly and deletes the temp files
Zuur
  • 101
  • 1
  • 6