Inno Setup:字幕样式进度条,用于在C#DLL中进行长时间的同步操作 [英] Inno Setup: Marquee style progress bar for lengthy synchronous operation in C# DLL
问题描述
我使用Inno Setup为我的程序创建安装程序.我有代码C#,并且有一些向导页面可以运行它.当我的代码C#长时间工作时,我想查看"ProgressBar"(字幕类型).我想不理解我的代码C#正在工作或正在挂起.如何在Inno Setup中为我的代码C#创建"ProgressBar"(字幕框样式).谢谢你的任何想法.
I create setup for my program using Inno Setup. I have code C# and some wizard page runs it. I want to see "ProgressBar" (style Marquee) when my code C# works a long time. I want to undectend my code C# is working or hanging. How create a "ProgressBar" (style Marquee) in Inno Setup for my code C#. Thank you for any idea.
ProgressBar示例:
Example ProgressBar:
某些代码:
[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线程.因此,您无法为进度条设置动画.
This is not easy. Calling into synchronous function effectively blocks the GUI thread. So you cannot animate the progress bar.
您必须在另一个线程上运行冗长的任务.由于它似乎是您的DLL,因此您可以对其进行修改以提供异步API.像这样:
You have to run the lengthy task on a different thread. As it seems to be your DLL, you can modify it to offer an asynchronous API. Something like:
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中使用它,例如:
And then you can use this from Inno Setup like:
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;
有关类似问题,请参见:
如何延迟而不冻结-Inno Setup
For a similar question see:
How to Delay without freezing - Inno Setup
这篇关于Inno Setup:字幕样式进度条,用于在C#DLL中进行长时间的同步操作的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!