Combine Setup MSI and EXE into a single package with IExpress
IExpress is a little known utility that will combine any number of files into a single, self-extracting executable similar to a WinZip self-extracting executable except IExpress comes standard with XP, Vista, and Windows 7 and is therefore free.
A tool like this one is especially handy as a standard Visual Studio setup project will produce two files: an MSI for your application and a setup EXE (the bootstrapper) for any prerequisites. Because I didn’t want to have to tell my client, “First you need to run the EXE, and then run the MSI”, I had to have something that would package both of these files into a single package. IExpress does this quite nicely, though there was a bit of a hurdle to overcome (see below).
First, you can find IExpress in the Windows System32 folder. It’s an executable that, when run, will present this dialog:
I’m not going to go into how to create your first SED file but will instead refer you to this step-by-step tutorial.
Of more interest to me was how to automate the creation of the single package as part of my setup project. Once you have a configured SED, you can use the following command-line syntax in your setup’s post-build step to create the single IExpress installer:
IExpress /N /Q $(ProjectDir)myapp.sed
The SED contains all of the info IExpress needs including which files to package up and where to output the final EXE.
I did run into a very annoying issue which burned more than a few hours. I’ll detail it here so maybe you won’t waste as much time as I did.
My IExpress package contains the following files:
Setup.bat is the only thing I tell IExpress to run:
The problem with this is that somewhere between VS2005 and VS2008, Microsoft introduced a bug which causes executables launched by self-extracting exe’s (produced by IExpress, InstallShield, WinZip, and probably others) to not wait for an accompanying MSI to finish installing. In fact, in the case of IExpress, it appears to remove the MSI before setup.exe has even run it, resulting in this error dialog once setup.exe is ready to hand-off the install to the MSI:
Long story short, a poster here came up with a nice workaround. Setup your SED as above, with a batch file included in the contents and make the batch file the only thing IExpress launches. The contents of the batch file are as follows:
MKDIR %Tmp%<UNIQUE PRODUCT NAME>
XCOPY . %Tmp%<UNIQUE PRODUCT NAME> /S /E /Y
%Tmp%<UNIQUE PRODUCT NAME>setup.exe
Where <UNIQUE PRODUCT NAME> is your application or some other name. Create your new IExpress package EXE either by going through the wizard again or running the command-line as above. If you then launch the package EXE once setup.exe has finished with the prereq’s (if any), your MSI should launch.
This workaround has the side-effect of leaving the extracted files behind, but you can always add a final step to remove them.