我有一个Inno Setup安装,执行一些耗时的'AfterInstall'操作。执行此操作时,安装GUI完全冻结(似乎未处理主事件循环)。这不是一个愉快的最终用户体验,所以也许这种操作可能不会冻结GUI?比如在单独的线程中执行它或定期调用handleGuiEventLoop()
之类的东西?
答案 0 :(得分:5)
output progress pages旨在提供有关较长时间运行操作的反馈。
但为了使其有效,您必须能够通过定期调用此页面上的方法来保持Inno更新您当前的进度。
有一个图书馆会让你pass an Inno script function as a callback to a DLL,这可能是有用的。您可能还想查看使用同一站点的ITDownload脚本,这样您就可以从Inno本身进行HTTP访问,避开中间人。
然而,Inno本质上是单线程和GUI线程仿射,因此直接调用阻塞操作将始终阻止UI而无需特殊规定。可以在单独的线程中运行代码(但只能在DLL中,并且您必须非常小心);其他选项包括仅进行异步调用,或内部维护GUI更新的调用,例如Exec
。
答案 1 :(得分:1)
有两种方法可以改善体验(它们与API的观点不同,内部两者都是相同的 - 它们会抽取Windows消息队列):
使用TOutputProgressWizardPage
来显示操作进度。其Delete File
方法在内部调用VCL TApplication.ProcessMessages
,它会为Windows消息队列提供支持。
使用CreateOutputProgressPage
创建页面。
一些例子:
通过调用WinAPI DispatchMessage
显式抽取Windows消息队列。
有些示例,请参阅SetProgress
函数:
在这两种情况下,您都必须添加触发消息队列抽取的调用。通常在一些循环中进行处理。
在某些情况下,您无法做到这一点。例如,当您使用对外部应用程序的阻止调用(例如,使用Exec
或ShellExec
)进行处理时。您可以通过在函数运行时安排定期触发的计时器来解决此问题。
上面链接的一些例子使用了这种方法,即: