Search code examples
inno-setupsleeppascalscript

How to delay without freezing in Inno Setup


Hello I like to know how can I delay a work (or a command) for a specified time in Inno Setup Pascal Script.

The built in Sleep(const Milliseconds: LongInt) freezes all work while sleeping.

And the following function I implemented also makes the WizardForm unresponsive but not freezing like built in Sleep() Function.

procedure SleepEx(const MilliSeconds: LongInt);
begin
  ShellExec('Open', 'Timeout.exe', '/T ' + IntToStr(MilliSeconds div 1000), '', SW_HIDE,
            ewWaitUntilTerminated, ErrorCode);
end;

I also read this, but can't think how to use it in my function.

I like to know how can I use WaitForSingleObject in this SleepEx function.

Thanks in advance for your help.


Solution

  • Use a custom progress page (the CreateOutputProgressPage function):

    procedure CurStepChanged(CurStep: TSetupStep);
    var 
      ProgressPage: TOutputProgressWizardPage;
      I, Step, Wait: Integer;
    begin
      if CurStep = ssPostInstall  then
      begin
        // start your asynchronous process here
    
        Wait := 5000;
        Step := 100; // smaller the step is, more responsive the window will be
        ProgressPage :=
          CreateOutputProgressPage(
            WizardForm.PageNameLabel.Caption,
            WizardForm.PageDescriptionLabel.Caption);
        ProgressPage.SetText('Doing something...', '');
        ProgressPage.SetProgress(0, Wait);
        ProgressPage.Show;
        try
          // instead of a fixed-length loop,
          // query your asynchronous process completion/state
          for I := 0 to Wait div Step do
          begin
            // pumps a window message queue as a side effect,
            // what prevents the freezing
            ProgressPage.SetProgress(I * Step, Wait);
            Sleep(Step);
          end;
        finally
          ProgressPage.Hide;
          ProgressPage.Free;
        end;
      end;
    end;
    

    The key point here is, that the SetProgress call pumps a window message queue, what prevents the freezing.

    enter image description here


    Though actually, you do not want the fixed-length loop, instead use an indeterminate progress bar and query the DLL in the loop for its status.

    For that, see Marquee style progress bar in Inno Setup for lengthy synchronous operation in C# DLL.