很长的Exec
正在安装.NET 3.5,输出脚本基于此:http://www.blackhillsoftware.com/blog/2006/06/26/using-innosetup-with-the-dotnet-framework/
问题是它正在使用ewWaitUntilTerminated
,因为我们需要捕获退出代码。由于我们正在运行它/passive /norestart
,因此它变得更糟了,从而减少了用户的工作量(也许我们不应该这样做)。
我能想到的最简单的选择是在安装.NET时隐藏窗口,并在完成后再次显示它,但是我不确定该怎么做。
理想的解决方案是显示进度页,但似乎不可能,因为我们需要立即返回,但是在流程退出并捕获退出代码时仍会以某种方式得到通知,否则会有一个永恒的进度栏。
关于此事的任何想法?
编辑:最小化可能会更好,但是也不知道如何做到这一点。我们确实会显示一条消息,通知用户该过程可能需要10到20分钟,但是问题是主设置表单已完全冻结,无法移动,最小化或对其执行任何操作。同样运行/passive
的.NET安装程序在较慢的计算机上实际上一两分钟都没有显示任何进度。
我们需要通过几个产品安装.NET,并采取了两种方法:
老实说,我们对第二个选项的运气更好,尤其是现在越来越多的系统管理员似乎在一定程度上锁定了台式机。
使Inno Setup看起来“不冻结”的一种方法是添加一个“伪装”进度指示器,例如选取框,以表明发生了某些事情。但这无法解决“窗口不可拖动/移动”的问题。
因此,另一种方法是在执行长时间运行的过程时真正解冻Inno Setup GUI:通过ShellExecuteEx()
执行“长时间运行过程”。然后,安装程序使用带有条件的while循环WaitForSingleObject
和非常小的超时执行AppProcessMessage
。
AppProcessMessage
本身是一个辅助函数。它使用WinAPI函数Application.ProcessMessages
,PeekMessage()
和TranslateMessage()
,使用“通用”代码重新创建DispatchMessage()
类程序。它的工作是成为Inno Setup GUI的消息泵。
此技巧使窗口再次响应/可拖动,而“长时间运行的过程”是在后台处理的。
这是执行循环的来源:
if ShellExecuteEx(ExecInfo) then
begin
while WaitForSingleObject(ExecInfo.hProcess, 100) = WAIT_TIMEOUT
do begin
AppProcessMessage;
WizardForm.Refresh();
end;
CloseHandle(ExecInfo.hProcess);
end;
以下unzip.iss
的GIST包含独立Unzip Helper for executing 7zip without blocking the Inno Setup GUI的代码,包括用于AppProcessMessage
功能的位和片段。
在这种情况下,“解压缩”只是一个例子,您可以用.NET安装程序或任何其他长期运行的任务替换执行的应用程序。
尽管可能很容易,但我不建议在.Net安装程序运行时隐藏您的安装程序。我见过其他安装程序会这样做,当安装程序发生时,我认为安装已完成,然后当我发现安装程序确实没有安装时,我感到困惑。 (并且当安装真正完成时,我也不能确定。也许只是再次隐藏了自己。)
您可以在Inno Setup向导中显示自定义页面。使这样的页面显示进度条并保持其准确性可能是一个挑战,但是至少您可以在向导页面上显示一条消息,指出您的安装程序正在等待.Net安装程序之后再继续。请参阅帮助文件的“使用自定义向导页面”部分。
您可以通过调用简单地隐藏安装程序向导表单
WizardForm.Hide;
Exec(...);
WizardForm.Show;
尽管我同意这不是很漂亮。
问了问题已经有5年了,但是无论如何,这是我的答案。
在调用Exec()之前,您可以设置将由Inno Setup显示的消息,位于主进度条上方,如下所示:
WizardForm.StatusLabel.Caption := 'Installing .NET Framework 3.5. Please wait, this can take up to 1 hour...';