代码之家  ›  专栏  ›  技术社区  ›  Blueeyes789

如何在Inno设置中延迟而不冻结

  •  2
  • Blueeyes789  · 技术社区  · 8 年前

    你好,我想知道如何在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 回复  |  直到 5 年前
        1
  •  6
  •   Martin Prikryl    3 年前

    使用自定义进度页( 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 call泵送一个窗口消息队列,这可以防止冻结。

    enter image description here


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

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