长的Exec正在安装.NET 3.5,并且脚本基于这个:http: //www.blackhillsoftware.com/blog/2006/06/26/using-innosetup-with-the-dotnet-framework/
问题是它使用"ewWaitUntilTerminated"因为我们需要捕获退出代码.由于我们正在运行它/ passive/norestart,因此它对用户的影响较小(也许我们不应该?),这会让情况变得更糟.
我能想到的最简单的选择是在安装.NET时隐藏窗口并在完成后再次显示它,但我不知道该怎么做.
理想的解决方案是显示一个进度页面,但它似乎不可能,因为我们需要立即返回,但在进程退出并捕获退出代码时仍然会以某种方式通知,否则我们会只是有一个永恒的进步吧.
关于如何解决这个问题的任何想法?
编辑:最小化可能会更好,但不知道如何做到这一点.我们会显示一条消息,通知用户该过程可能需要10-20分钟,但问题是主设置表单已完全冻结,无法移动,最小化或对其执行任何操作.同样运行/被动.NET安装程序实际上并没有在较慢的机器上显示任何一两分钟的进度.
使Innosetup"看起来不冻结"的一种方法是添加一个"假的"进度指示器,就像一个选框,以显示正在发生的事情.但这不会解决"窗口不可拖动/可移动"的问题.
因此,另一种方法是真正解冻Innosetup GUI,同时执行一个长时间运行的进程:
"长时间运行的进程"通过ShellExecuteEx()执行.然后安装程序使用带有条件的while循环
WaitForSingleObject
和一个非常小的超时来执行AppProcessMessage
.
AppProcessMessage
本身就是一个辅助功能.它使用"通用"代码重新创建"Application.ProcessMessages"-ish过程,使用WinAPI函数PeekMessage()
,TranslateMessage()
和DispatchMessage()
.它的工作是成为InnoSetup GUI的消息泵.
这个技巧使窗口响应/可拖动,而"长时间运行的过程"在后台处理.
这是执行循环的来源:
if ShellExecuteEx(ExecInfo) then begin while WaitForSingleObject(ExecInfo.hProcess, 100) = WAIT_TIMEOUT do begin AppProcessMessage; WizardForm.Refresh(); end; CloseHandle(ExecInfo.hProcess); end;
以下GIST unzip.iss
包含用于执行7zip的独立Unzip Helper的代码,而不会阻止InnoSetup GUI,包括用于处理该AppProcessMessage
函数的位和部分.
在这种情况下,"解压缩"只是一个示例,您可以用任何,.Net安装程序或任何其他长时间运行的任务替换已执行的应用程序.