Inno Setup:用于 C# DLL 中冗长同步操作的 Marquee 样式进度条

Inno Setup: Marquee style progress bar for lengthy synchronous operation in C# DLL

我使用 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;

    

这并不容易。调用同步函数有效地阻塞了 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;

类似问题见: