8

The long Exec is installing .NET 3.5, and out script is based off this one: http://www.blackhillsoftware.com/blog/2006/06/26/using-innosetup-with-the-dotnet-framework/

The problem is that it's using ewWaitUntilTerminated because we need to capture the exit code. It's made a little worse by the fact that we're running it /passive /norestart so that it's less work on the user's part (Maybe we shouldn't?)

The easiest option I could think of is to hide the window while it's installing .NET and showing it again after it's done, but I'm not sure how to do that.

The ideal solution would be to show a progress page, but it doesn't seem like it'd be possible since we'd need to return right away but somehow still be notified when the process exits and capture the exit code otherwise we'd just have an eternal progress bar.

Any ideas on how to go about this?

Edit: Minimizing would probably be better, but not sure how to do that either. We do display a message informing the user that the process may take 10-20 minutes, however the problem is that the main setup form is completely frozen, can't move, minimize or do anything with it. Also running /passive the .NET installer doesn't actually show any progress for a good minute or two on a slower machine.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Davy8
  • 30,868
  • 25
  • 115
  • 173
  • Having just spent an afternoon installing a demo of an app that didn't start out by warning me that it would want .NET 3.5 until after the first mandatory reboot... lets just say that users can get touchy about unexpected long sub-installs. I don't have a technical answer, however. – RBerteig Mar 04 '09 at 10:38
  • Then .NET also required a reboot, after which the original app's setup had long since forgotten it was running, and had to be found manually in a temp folder and re-run to actually install the application. – RBerteig Mar 04 '09 at 10:40
  • Yeah, we inform that user and allow them to cancel before the framework is installed, and we suppress the .net installer's reboot and capture it in the return code to perform the reboot ourselves – Davy8 Mar 04 '09 at 16:16
  • See also [my answer to Inno Setup: How to modify long running script so it will not freeze GUI?](https://stackoverflow.com/q/14385393/850848#45071489) – Martin Prikryl May 30 '18 at 07:32

5 Answers5

10

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.

Martin Prikryl
  • 188,800
  • 56
  • 490
  • 992
Jens A. Koch
  • 39,862
  • 13
  • 113
  • 141
2

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.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • We do have something similar that that, however, the Exec is running on the same thread, so the user is unable to move, resize, minimize or do anything with the setup form. – Davy8 Feb 26 '09 at 19:20
  • (I personally thought it was fine, but my boss complained about it and insisted it was unacceptable) – Davy8 Feb 26 '09 at 19:20
  • 1
    @Davy8: Your first comment isn't entirely true - it's running on the same thread, but Application.ProcessMessages() is called. The wizard form is however disabled, so moving, resizing etc. isn't possible. – mghie Feb 26 '09 at 19:45
2

You can simply hide the installer wizard form by calling

WizardForm.Hide;
Exec(...);
WizardForm.Show;

though I agree that this is not really pretty.

mghie
  • 32,028
  • 6
  • 87
  • 129
0

It's been 5 years since you've asked the question but here is my answer anyway.

Before calling Exec() you can set the message that will be shown by Inno Setup above the main progress bar like this:

WizardForm.StatusLabel.Caption := 'Installing .NET Framework 3.5. Please wait, this can take up to 1 hour...';
bogdan
  • 161
  • 1
  • 9
  • Except that you can also [`show a marquee progress bar`](http://stackoverflow.com/a/20753218/960757). Besides, you should store the caption of the `StatusLabel` and restore it back when changing it. – TLama Apr 27 '14 at 09:23
0

We've needed to install .NET with a couple products, and have taken two approaches:

  • When installing .NET with Innosetup, we let the user know that the installation will take a long time, and to expect a certain message when it is complete
  • We start the .NET set up without any flags to force the client through it. This way if they're more technically inclined they know why the install is taking so long

We've honestly had better luck with the 2nd option, particularly now that more system admins seem to lock down desktops to a certain degree.

Beep beep
  • 18,873
  • 12
  • 63
  • 78
  • Yeah, we're currently using the first approach, and considering the 2nd one, but wondering if there's a better solution – Davy8 Feb 26 '09 at 19:26