We are in the process of updating the construction of our product's .msi package for Windows Server 2008. The main component of our install is an application that is run as a Windows service. There is also a configuration application that gets run during install to set up registry entries for use by the service.
The service and the configuration application rely on the Microsoft C/C++ runtime and MFC, which are included in the .msi as merge modules. The assemblies for the C/C++ runtime and MFC are committed during the InstallFinalize, which seems to preclude the starting of the service using the mechanisms provided by Windows Installer (is this correct?) Certainly, we see side-by-side errors with at least the configuration application if it is run before InstallFinalize.
The approach we have taken is to run the configuration application as a "commit" custom action after InstallFinalize, and have this application start the service. This requires that the application is executed with elevated privileges (for which we use a manifest containing a trustInfo section.) This further requires that the .msi is configured to run this application without Impersonation (which otherwise confounds the privilege elevation.)
Is this an acceptable approach? How future-proof is this likely to be? Are there any gotchas to be aware of?
It seems that this is a problem that has been encountered by others:
Is there an officially (or unofficially) accepted way to deal with such problems?
As an addendum to this, is there any way of ensuring that an application run as a custom action during the install process gets focus when it starts up? Applications started in this manner always seem to pop up behind the installer and the installer keeps focus, which is not a particularly user-friendly effect.
Here's a solution I've used for this kind of problem when re-packaging software with Windows Installer: a "bootstrap" launcher. In short, instead of using the merge modules for the runtime (which will all commit at the same time as all your other installed files), you can do one of the following:
Provide the redistributable MSIs for the runtime/MFCs, and have them launched first by your bootstrapper setup.exe. Your program's MSI must of course test that the version you need is installed and maybe even test to ensure that you're running it from your setup.exe. (This method was popularized by InstallShield, as they like to do the end-run around Windows Installer.)
Better yet, you can package your MSI as a parent package that installs two (or more) embedded MSIs: first, install the required runtimes, then install your software in a child MSI. Your parent package will confirm that the runtimes' MSI installed successfully before continuing on to install your MSI (which has the freedom to start the services since the prerequisites are already there).
There are other tricksy methods, like your early-commit custom action, but they are not as dependable as the time-tested ones I just mentioned.
Hope that makes sense! I used to live and breathe MSI, but not so much anymore these days...