我正在处理的安装程序在PrepareToInstall
函数中完成大部分工作,因为我需要做的所有事情都可能失败,因此这是处理这些事情的适当位置,以防它们执行失败。通过在函数的结果中传递错误消息,可以自动报告任何故障。安装程序实际上只复制了3个小文件。
问题是该向导似乎在此功能期间冻结(或不响应),只显示一个标题为"准备安装的空白页..."实际上,它正在经历我的安装过程。
我想通过简单的程序ShowProgress(const S: String);
向用户显示进度,向用户显示其实际执行的操作。我怎么能这样做?
这就是我安装的方式,我希望将每次通话都打包到Log()
...
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
R: Integer;
begin
Result:= '';
try
Log('Doing this...');
R:= DoThis;
case R of
0: begin
Result:= '';
end;
1: begin
Result:= 'Error message 1 was raised while doing this.';
end;
else begin
Result:= 'Unexpected error doing this: ' + IntToStr(R);
end;
end;
if Result = '' then begin
Log ('Doing that...');
R:= DoThat;
case R of
0: begin
Result:= '';
end;
1: begin
Result:= 'Error message 1 was raised while doing that.';
end;
else begin
Result:= 'Unexpected error doing that: ' + IntToStr(R);
end;
end;
end;
if Result = '' then begin
Log ('Doing something else...');
R:= DoSomethingElse;
case R of
0: begin
Result:= '';
end;
1: begin
Result:= 'Error message 1 was raised while doing something else.';
end;
else begin
Result:= 'Unexpected error doing something else: ' + IntToStr(R);
end;
end;
end;
//A few more blocks like above
//Error logging
if Result <> '' then begin
Log('FAILURE: '+Result);
end;
except
Result:= 'EXCEPTION';
Log('EXCEPTION');
end;
end;
答案 0 :(得分:11)
我把所有答案都混合了,我找到了另一个可能解决这个问题的方法。
我知道这不是一个所谓的优雅解决方案。 无论如何,它是一个快速的解决方案,可以避免您使用自定义控件开发一个单独的DLL来管理安装程序和DLL之间的通信。
以下方法描述了如何在PrepareToInstall
设置阶段创建自定义页面,该页面是Page Inno Setup的副本。
此副本必须具有与原始副本相同的外观,加上进度条和开发人员可用于指示PrepareToInstall
设置阶段当前步骤的标签。
让我们看一些代码 首先,准备自定义页面:
[Code]
var
PrepareToInstallWithProgressPage : TOutputProgressWizardPage;
现在定义PrepareToInstall
函数来添加我们的自定义内容:
function PrepareToInstall(var NeedsRestart: Boolean): String;
var
ResultCode: Integer;
begin
PrepareToInstallWithProgressPage.SetProgress(0, 0);
PrepareToInstallWithProgressPage.Show;
try
// First preinstallation step: suppose to kill currently app you are going to update
PrepareToInstallWithProgressPage.SetText('Exiting MyApp Running Instances'), '');
ExecuteCmd('taskkill', '/F /IM MyApp');
// Set progress bar to 10%
PrepareToInstallWithProgressPage.SetProgress(1, 10);
// Second preinstallation step
// DoSomething usefull...
// Set progress bar to 20% after done
PrepareToInstallWithProgressPage.SetProgress(2, 10);
// ...do other preinstallation steps till the end
PrepareToInstallWithProgressPage.SetProgress(10, 10);
finally
PrepareToInstallWithProgressPage.Hide;
end;
end;
在此安装阶段,我们完成了准备安装阶段的步骤,因此Inno Setup的默认PrepareToInstall
页面会显示一段时间。
现在,用户可能无法理解页面发生了变化,因为我们的PrepareToInstallWithProgressPage
具有与原始页面相同的外观和感觉。
为了让我们的页面具有相同的外观,我们可以使用SetupMessage
函数获取原始Inno Setup PrepareToInstall
页面的2个字符串。
使用SetupMessage
,我们可以避免复制和本地化我们的自定义页面的字符串以复制原件。
就像这样:
procedure InitializeWizard;
var
A: AnsiString;
S: String;
begin
// The string msgWizardPreparing has the macro '[name]' inside that I have to replace with the name of my app, stored in a define constant of my script.
S := SetupMessage(msgPreparingDesc);
StringChange(S, '[name]', '{#MY_APPNAME}');
A := S;
PrepareToInstallWithProgressPage := CreateOutputProgressPage(SetupMessage(msgWizardPreparing), A);
end;
我希望这有帮助。
答案 1 :(得分:2)
查看Inno附带的CodeDlg.iss
示例脚本,特别是使用CreateOutputProgressPage
的代码。
此页面类型允许您在执行其他操作时显示状态消息和/或进度条。每当您更改进度标签/值时,它都会自动提取消息,以确保用户看到正确的状态。
准备用于这种代码。
答案 2 :(得分:0)
用PrepareToInstall
函数编写的代码阻止Windows消息泵处理,使向导形式无响应。如果需要在此屏幕中显示许多控件,可能显示进度条和要执行的步骤列表,则可以使用DLL内部的表单来完成此操作。确保此DLL中有一个执行实际安装过程的线程,并且只更新GUI以向用户显示状态。例如,此DLL表单可能会覆盖向导,甚至可能会在自定义向导页面中嵌入向导内部。我们的想法是将您的安装代码从PrepareToInstall
函数移动到此线程中,然后才能在此过程中实现完全响应的GUI。从PrepareToInstall
函数,应该只有一个DLL调用来启动安装过程,而这反过来又显示了DLL中的表单。
结果可能看起来像这样(在工作中):