如何延迟不冻结 - Inno Setup

时间:2016-10-03 05:51:40

标签: inno-setup sleep pascalscript

您好我想知道如何在Inno Setup Pascal Script中延迟指定时间的工作(或命令)。

内置Sleep(const Milliseconds: LongInt)会在睡觉时冻结所有工作。

我实现的以下功能也使WizardForm无法响应但不像内置Sleep()函数那样冻结。

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

我还阅读了this,但无法想到如何在我的函数中使用它。

我想知道如何在此WaitForSingleObject函数中使用SleepEx

先谢谢您的帮助。

1 个答案:

答案 0 :(得分:2)

使用自定义进度页面(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;

这里的关键点是,SetProgress调用泵送一个窗口消息队列,这可以防止冻结。

enter image description here

虽然实际上,你不需要固定长度的循环,而是使用不确定的进度条并在循环中查询DLL的状态。

为此,请参阅Inno Setup: Marquee style progress bar for lengthy synchronous operation in C# DLL