Skip to main content
Email Password   helpLost your password?
sfxui.PNG

Introduction

I recently ran into a problem where I required a self-extracting installer that would allow customers to download one single huge file in order for them to choose from a variety of setups or associated documents, like readme files or release notes. Consider a company that ships a product suite that is made up of different components like a server installation, a client installation, an administrative installation, and a command line tools installation. If each of those components has a separate setup program or an MSI file that customers have to download, this is soon going to be tedious for the customer. Having all relevant setups for each component combined in one big self-extracting installer with a user interface that allows for the selection of an individual component would be the ideal solution for this problem.

Requirements

I came up with the following requirements for the solution to this problem:

Solution Overview

As the compression format, I chose the zip format. There are a number of constraints or limitations in using the zip format, that I will outline below. At creation time of the self-extracting installer, a zip file, containing all files that make up the installation, is appended to a stub file (sfx.exe). The stub will extract a couple of files, immediately at runtime, into a temporary directory, and then launch a child process (setupui.exe) that implements the user interface that can be seen in the screenshot at the top of the article. The creation of a self-extracting installer is done with the program sfxmaker.exe that is built as part of this project. Using sfxmaker.exe, you can specify which files go into the self-extracting installer and which components of the self-extracting installer are offered to the user at runtime. You can also brand your self-extracting installer with your company's name so that the self-extracting installer's file version information contains your company and product name. In addition, several localization aspects can be done with sfxmaker, such as the text on the labels and buttons of the self-extracting installer's user interface.

For each component to be installed, you can specify a custom icon that appears in the list control of the self-extracting installer next to the component's description. For this to work, those icon files have to be added to the project, and must be extracted during startup of the self-extracting installer so they can be shown immediately. As a convention, all files to be extracted at startup of the self-extracting installer must start with "setupui", so these icon files must have names that start with "setupui" as well. Some files to be extracted at startup of the self-extracting installer have predefined names: If there is a file named setupui.bmp, it will be displayed on the self-extracting installer user interface like the bitmap with the bubbles in the screenshot above. If a file named setupui.ico is contained in the self-extracting installer package, it will be used as the icon of the self-extracting installer when Alt-tabbing between applications, so it is best if you add your product's icon file as setupui.ico to the installer package in sfxmaker. If a file named setupui.avi is contained in the self-extracting installer package, it will be displayed in a progress dialog if a setup program is invoked from the self-extracting installer while the installation runs, unless the setup is an MSI installation.

Sfxmaker.exe is a document view model based MFC application that works with documents with the file name extension sfx. One such sfx document created by sfxmaker.exe describes exactly one self-extracting installer binary, and has the format of a Windows INI file, albeit in UNICODE format (UTF-16). This makes an SFX file human readable, and also perfectly suited for source control systems. At creation time of the self-extracting installer package, this SFX document file is added as setupui.ini to the zip file, and setupui.exe can extract all relevant information at runtime from this file.

Seeing the Installer at Work

In order to get an impression of how such a self-extracting installer package works, please download the self-extracting installer demo, unpack and execute it. This demo shows the fictitious foobar application suite that shows the various components in the list control that can be installed or launched. The first two components launch MSI files for the foobar server and client. These two components show the special treatment of MSI based setups, because the self-extracting installer window acts as a parent window for the MSI installer windows. Now, launch the third setup, the foobar tools setup. This setup is also MSI based, but it is launched via a special command line using msiexec. Notice that there is no parent-child relationship of the self-extracting installer window and the MSI user interface, in this case, and that the self-extracting installer shows a progress dialog while this setup is running. You can override the relatively boring animation in this progress dialog if you specify a setupui.avi file in your self-extracting installer package, as mentioned before. The fourth component starts an executable that demos how you can add arbitrary EXE files to be executed from your self-extracting installer package. Notice that you will also see the progress dialog in this case.

The last two entries allow the user to launch a PDF file with the release notes and a readme text file. For both components, the icons that are displayed in the list control are extracted at runtime from the associated applications, which are Acrobat Reader and Notepad, in most cases. Extracting the associated icons at runtime helps you display the Acrobat icon without adding it to your installer package, which would be a violation of Adobe's copyrights. If there is no associated application with a file to be ShellExecute'd, like it is done with the readme file or the PDF file, then there is simply no icon visible for the list control entry of the setup component.

Running sfxmaker

In this paragraph, I will show how you can recreate the self-extracting installer demo from existing source files. This way, you will get a rough idea of what you have to do in order to create your own self-extracting installer for your product. First, download the demo project for a self-extracting installer, and unzip it with directory preservation into the drive c:\ root directory. The files that make up this demo project should now all be in the directory c:\sfxdemo. You will see that this directory contains the individual MSI files for the foobar client, server, and tools installation. You will also see a couple of *.ico files for the individual setups, and the readme.txt and the relnote.pdf files. Now, download the project's source code into an empty directory of your hard disk, and find the release directory with the sfxmaker.exe file in it, and launch it. The user interface of sfxmaker.exe will look like:

Now, open the file c:\sfxdemo\sfxdemo.sfx in sfxmaker and notice how all the user interface elements are populated:

Now, click the button labelled "Create SFX". This will prompt you now for the name and location of the resulting self-extracting installer. Choose a name and location of your liking, and click OK. It will now take a few seconds, and then the self-extracting installer will have been created for you.

Adding and Updating Components

If you add a new component or update an existing one in sfxmaker, a dialog like the following will be presented to you:

The items that you can specify for each component here are as follows:

For the "Application" and "Command Line" items, you can specify text that contains environment variables. They will be resolved at runtime by the self-extracting installer. You can use the special environment variable CURRENTDIRECTORY. This environment variable expands, at runtime, to the temporary directory where the files are uncompressed to by the self-extracting installer. Look at how the "Foobar Tools 1.0" installation in the demo project uses this variable so msiexec.exe finds the MSI file. Make sure that you add a corresponding file name to the "Files" list box for every component's "File to unpack" you add. Also make sure you add each icon file to the "Files" list box.

Using the Code

Use Visual Studio 2005 with a Vista SDK or a Server 2008 SDK integrated to compile the project. A bare bones Visual Studio 2005 installation will not work because for some reason beyond my imagination, Visual Studio 2005 is missing the import library for msi.dll, msi.lib. In addition, I heavily use PREfast __analysis_assert statements in my code in order to make it PREfast-clean. You can also use Visual Studio 2008 which will convert the solution and project files for you into the Visual Studio 2008 format. For both development environments, you need a variant that contains MFC, so the express editions will not suffice. In order to compile the project files, first extract the source code for this article recursively into an empty directory on your hard disk. Under the project's sfx directory, create a subdirectory named zlib123 which then should be in parallel with the subdirectories include, lib, mc, setupui, sfxmaker, sfx zlibstat, and sfxcommn. This is because you also need the current version of the zlib library, version 1.2.3. Download a copy of the library here. Unzip the zlib files into this directory, again with directory preservation. Now, you should be able to compile the whole project.

Limitations

The current implementations suffer from three main limitations, you have to judge yourself if they are problems for you:

Extracting All Files

Using the command line parameter -e or -x you can extract the content of a self-extracting installer into a directory. Specifying only -e as the command line parameter will show a directory picker dialog that you can use to select or create a directory, where all files in the self-extracting installer should be extracted to. If you use -e=targetdirectory or -x=targetdirectory as the command line parameter, all files will be extracted to the target directory without showing the directory picker dialog. So for example, if you specify -e=c:\foobar, all files will be extracted to the directory c:\foobar. If necessary, the directory will also be created.

Trivia

You can open a self-extracting installer built with the code and binaries from this article with Total Commander, much like a zip file. Just select the file and type Ctrl-Pagedown. You can then select individual files from the self-extracting binary and copy them from there to somewhere else.

Future Outlook

It would be interesting to change the user interface that is presented via setupui.exe to an HTA-based user interface. This way, the design of the UI could be entirely left to the user and his/her HTML skills. Adding a command line option to sfxmaker to run it in an automated way from a build script would also be something real cool.

History

You must Sign In to use this message board.
 
 
Per page   
 FirstPrevNext
GeneralDeplying my application from VISTA Pin
AlexEvans
13:45 10 Aug '09  
GeneralRe: Deplying my application from VISTA Pin
kustt110
7:11 15 Aug '09  
GeneralRe: Deplying my application from VISTA Pin
AlexEvans
12:21 15 Aug '09  
GeneralRe: Deplying my application from VISTA Pin
kustt110
9:09 21 Aug '09  
GeneralRe: Deplying my application from VISTA Pin
AlexEvans
14:23 21 Aug '09  
GeneralRe: Deplying my application from VISTA Pin
kustt110
11:17 25 Aug '09  
GeneralSource Code Size Pin
knestel
20:52 1 Dec '08  
GeneralRe: Source Code Size Pin
Stefan Kuhr
9:21 7 Dec '08  
Generalfolders Pin
Member 4510372
17:58 27 Nov '08  
GeneralRe: folders Pin
Stefan Kuhr
9:25 7 Dec '08  
GeneralCan I use this or is there a program to put files/folders inside a pre installed game directory? Pin
ou8it
11:33 4 Nov '08  
AnswerRe: Can I use this or is there a program to put files/folders inside a pre installed game directory? Pin
Stefan Kuhr
11:18 15 Nov '08  
GeneralRe: Can I use this or is there a program to put files/folders inside a pre installed game directory? Pin
ou8it
13:47 25 Nov '08  
GeneralCan you please mention why you didn't use for example WIX of NSIS? Pin
Ramon Smits
3:13 23 Oct '08  
AnswerRe: Can you please mention why you didn't use for example WIX of NSIS? Pin
Stefan Kuhr
5:22 23 Oct '08  
GeneralRe: Can you please mention why you didn't use for example WIX of NSIS? Pin
Ramon Smits
5:48 23 Oct '08  
GeneralRe: Can you please mention why you didn't use for example WIX of NSIS? Pin
Stefan Kuhr
8:56 23 Oct '08  
GeneralHow can I compile it successfully? Pin
Johnson Zhou
23:19 20 Oct '08  
AnswerRe: How can I compile it successfully? Pin
Stefan Kuhr
5:30 23 Oct '08  
GeneralRe: How can I compile it successfully? Pin
Stefan Kuhr
9:03 23 Oct '08  
GeneralRe: How can I compile it successfully? Pin
Johnson Zhou
22:40 24 Oct '08  


Last Updated 12 Dec 2008 | Advertise | Privacy | Terms of Use | Copyright © CodeProject, 1999-2009