我有一个Inno安装程序安装执行一些耗时的'AfterInstall'操作。执行此操作时,安装GUI完全冻结(似乎未处理主事件循环)。这不是一个愉快的最终用户体验,所以也许这种操作可能不会冻结GUI?喜欢在单独的线程中执行它或定期调用类似handleGuiEventLoop()
的东西?
output progress pages旨在提供有关长时间运行操作的反馈。
但为了使其有效,您必须能够通过定期调用此页面上的方法来保持Inno更新您当前的进度。
有一个图书馆,可以让你pass an Inno script function as a callback to a DLL,这可能是有用的。您可能还想查看使用同一站点的ITDownload脚本,这样您就可以从Inno本身进行HTTP访问,避开中间人。
然而,Inno本质上是单线程和GUI线程仿射,因此直接调用阻塞操作将始终阻止UI而无需特殊规定。可以在单独的线程中运行代码(但只能在DLL中,并且必须非常小心);其他选项包括仅进行异步调用,或者内部维护GUI更新的调用,例如Exec
。
有两种方法可以改善体验(它们与API的观点不同,内部都是相同的 - 它们会抽取Windows消息队列):
TOutputProgressWizardPage
来呈现操作进度。它的SetProgress
方法在内部调用VCL TApplication.ProcessMessages
,它泵送Windows消息队列。
使用CreateOutputProgressPage
创建页面。
一些例子:
Inno Setup Get progress from .NET Framework 4.5 (or higher) installer to update progress bar position
How to Delay without freezing - Inno Setup
Inno Setup - Make Inno Setup Installer report its installation progress status to master installer
Inno setup: ExtractTemporaryFile causes wizard freeze
Inno Setup torrent download implementation
Inno Setup - How to add multiple arc files to decompress?DispatchMessage
显式地泵送Windows消息队列。
有关示例,请参阅AppProcessMessage
函数:
My SQL server discovery on LAN by listening port (Inno Setup)
How to execute 7zip without blocking the InnoSetup UI?
和别的在这两种情况下,您都必须添加触发消息队列抽取的调用。通常在一些循环中进行处理。
在某些情况下,您将无法做到这一点。例如,当您使用对外部应用程序的阻止调用(例如,使用Exec
或ShellExec
)进行处理时。您可以通过在函数运行时安排定期触发的计时器来解决此问题。
上面链接的一些例子使用了这种方法,即: