Inno Setup:如何修改长时间运行的脚本,以免它冻结GUI?

时间:2013-01-17 18:08:37

标签: inno-setup

我有一个Inno Setup安装,执行一些耗时的'AfterInstall'操作。执行此操作时,安装GUI完全冻结(似乎未处理主事件循环)。这不是一个愉快的最终用户体验,所以也许这种操作可能不会冻结GUI?比如在单独的线程中执行它或定期调用handleGuiEventLoop()之类的东西?

2 个答案:

答案 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消息队列):

  1. 使用TOutputProgressWizardPage来显示操作进度。Delete File方法在内部调用VCL TApplication.ProcessMessages,它会为Windows消息队列提供支持。

    使用CreateOutputProgressPage创建页面。

    一些例子:

  2. 通过调用WinAPI DispatchMessage显式抽取Windows消息队列。

    有些示例,请参阅SetProgress函数:

  3. 在这两种情况下,您都必须添加触发消息队列抽取的调用。通常在一些循环中进行处理。

    在某些情况下,您无法做到这一点。例如,当您使用对外部应用程序的阻止调用(例如,使用ExecShellExec)进行处理时。您可以通过在函数运行时安排定期触发的计时器来解决此问题。

    上面链接的一些例子使用了这种方法,即: