Inno Setup 中的字幕样式进度条,用于 C# DLL 中的长时间同步操作

问题描述 投票:0回答:1

我使用 Inno Setup 为我的程序创建设置。我有 C# 代码,一些向导页面运行它。当我的 C# 代码运行很长时间时,我希望看到“ProgressBar”(样式 Marquee)。我想了解我的 C# 代码是否正常工作或挂起。如何在 Inno Setup 中为我的 C# 代码创建“ProgressBar”(样式 Marquee)。谢谢你的任何想法。

进度示例:

一些代码:

[Files]
Source: "GetDataBases.dll"; Flags: dontcopy

[Code]

function ServerOfDataBases(
  scriptName, server, user, password,nameDB: string;
  out strout: WideString): Integer;
  external 'ServerOfDataBases@files:GetDataBases.dll stdcall';

var
  ServerDetailsPage: TInputQueryWizardPage;

function CallDB(scriptName, server, user, password, nameDB: string):string;
var
  retval: Integer;
  str: WideString;
begin  
  retval := ServerOfDataBases(scriptName, server, user, password, nameDB, str); 
  Result:= str; 
end;

procedure InitializeWizard;
var
 ...
begin
  ServerDetailsPage := CreateInputQueryPage(wpWelcome, '', '', '...');
  ServerDetailsPage.Add('Server...', False);
  ...
  ServerDetailsPage.Values[0] := '';
end;

function NextButtonClick(CurPageID: Integer): Boolean;
var
  DataDases: String;
...
begin
  ...  
  if CurPageID = ServerDetailsPage.ID then
  begin
    ...
    DataDases := '';
    scriptName := 'ListDB';
    DataDases := CallDB(
      scriptName, ServerDetailsPage.Values[0], ServerDetailsPage.Values[2],
      ServerDetailsPage.Values[3], '');
     ...
  end;
end;

    
inno-setup pascalscript
1个回答
3
投票

这并不容易。调用同步函数会有效地阻塞 GUI 线程。所以你不能为进度条设置动画。

您必须在不同的线程上运行冗长的任务。由于它似乎是您的 DLL,因此您可以修改它以提供异步 API。比如:

private static Task _task = null;
private static int _outcome;

[DllExport(CallingConvention = CallingConvention.StdCall)]
public static void StartSomething()
{
    // Starts an operation on a different thread
    _task = new Task(() => { Something(); });
    _task.Start();
}

// The operation to run on a different thread
private static void Something()
{
    // The lengthy operation
    Thread.Sleep(10000);
    // Remember the results
    _outcome = 123;
}

[DllExport(CallingConvention = CallingConvention.StdCall)]
public static bool HasSomethingCompleted(out int outcome)
{
    // Check if the operation has completed
    bool result = _task.IsCompleted;
    // And collect its results
    outcome = _outcome;
    return result;
}

然后您可以从 Inno Setup 中使用它,例如:

procedure InitializeWizard();
begin
  ServerDetailsPage := CreateInputQueryPage(wpWelcome, '', '', '...');
end;

procedure CallDll;
var
  ProgressPage: TOutputMarqueeProgressWizardPage;
  Outcome: Integer;
begin
  StartSomething;

  ProgressPage := CreateOutputMarqueeProgressPage('Calling DLL', '');
  ProgressPage.Show;
  try
    ProgressPage.ProgressBar.Style := npbstMarquee;
    // Wait for the Something to finish
    while not HasSomethingCompleted(Outcome) do
    begin
      ProgressPage.Animate;
      Sleep(50);
    end;

  finally
    ProgressPage.Hide;
    ProgressPage.Free;
  end;

  MsgBox(Format(
    'Something has finished and the outcome was %d', [Outcome]),
    mbInformation, MB_OK);
end;

function NextButtonClick(CurPageID: Integer): Boolean;
begin
  if CurPageID = ServerDetailsPage.ID then
  begin
    CallDll;
  end;
  Result := True;
end;

类似问题请参阅:
如何在 Inno Setup 中延迟而不冻结

© www.soinside.com 2019 - 2024. All rights reserved.