How do you make Inno Setup not look frozen while performing a long Exec?
One way of making Inno Setup "not look frozen" is to add a "fake" progress indicator, like a marquee, to show that something is going on. But this won't solve the "window not dragable / moveable" problem.
So, another way is to really unfreeze the Inno Setup GUI, while a long running process is executed:
The "long running process" is executed via ShellExecuteEx()
.
Then the installer uses a while loop with the condition
WaitForSingleObject
and a very minimal timeout
to execute AppProcessMessage
.
AppProcessMessage
is itself a helper function. It uses "generic" code to recreate a Application.ProcessMessages
-ish procedure, using the WinAPI function PeekMessage()
, TranslateMessage()
and DispatchMessage()
.
Its job is to be the message pump to the Inno Setup GUI.
This trick makes the window responsive/draggable again, while the "long running process" is processed in the background.
This is the source for the execution loop:
if ShellExecuteEx(ExecInfo) then
begin
while WaitForSingleObject(ExecInfo.hProcess, 100) = WAIT_TIMEOUT
do begin
AppProcessMessage;
WizardForm.Refresh();
end;
CloseHandle(ExecInfo.hProcess);
end;
The following GIST for unzip.iss
contains the code for a standalone Unzip Helper for executing 7zip without blocking the Inno Setup GUI, including the bits and pieces for working with the AppProcessMessage
function.
In this case "unzip" is just an example and you might replace the executed application with whatever, a .NET installer or any other long running task.
Although it probably would be easy, I don't recommend hiding your installer while the .Net installer runs. I've seen other installers do that, and when it happens, I think the installation is finished, and then I'm confused when I find that it's really not. (And when the installation really is finished, I can't be sure of that, either. Maybe it just hid itself again.)
You can display custom pages in the Inno Setup wizard. Making such a page show a progress bar and keeping it accurate would probably be a challenge, but at least you could display a message on the wizard page saying that your installer is waiting for the .Net installer before proceeding. See the "Using Custom Wizard Pages" section of the help file.
You can simply hide the installer wizard form by calling
WizardForm.Hide;
Exec(...);
WizardForm.Show;
though I agree that this is not really pretty.