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

问题描述 投票:3回答:2

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

inno-setup
2个回答
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
投票

有两种方法可以改善体验(它们与API的观点不同,内部都是相同的 - 它们会抽取Windows消息队列):

  1. 使用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?
  2. 通过调用WinAPI DispatchMessage显式地泵送Windows消息队列。 有关示例,请参阅AppProcessMessage函数: My SQL server discovery on LAN by listening port (Inno Setup) How to execute 7zip without blocking the InnoSetup UI? 和别的

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

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

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

© www.soinside.com 2019 - 2024. All rights reserved.