如何在 Inno Setup 中延迟而不冻结

How to delay without freezing in Inno Setup

您好,我想知道如何在 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,但想不出如何在我的函数中使用它。

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

在此先感谢您的帮助。

使用自定义进度页面(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 调用抽取一个 window 消息队列,防止冻结。


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

为此,请参阅