Inno设置:Marquee样式进度条,用于在C#DLL

时间:2017-08-24 08:22:40

标签: inno-setup

我使用Inno Setup为我的程序创建设置。我有代码C#,一些向导页面运行它。我想看看" ProgressBar" (样式Marquee)当我的代码C#工作很长时间。我想取消我的代码C#工作或挂起。如何创建一个" ProgressBar" (样式字幕)在Inno Setup中为我的代码C#。谢谢你的任何想法。

示例ProgressBar:

enter image description here

一些代码:

[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;

1 个答案:

答案 0 :(得分:1)

这并不容易。调用同步函数有效地阻止了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: TOutputProgressWizardPage;
  Outcome: Integer;
begin
  StartSomething;

  ProgressPage := CreateOutputProgressPage('Calling DLL', '');
  ProgressPage.Show;
  try
    ProgressPage.SetProgress(0, 100);
    ProgressPage.ProgressBar.Style := npbstMarquee;
    { wait for the Something to finish }
    while not HasSomethingCompleted(Outcome) do
    begin
      { And pump windows message queue frequently to animate the progress bar }
      ProgressPage.SetProgress(0, 100);
      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;

enter image description here

对于类似的问题,请参阅:
How to Delay without freezing - Inno Setup