Creating a bootstrapper with dotNetInstaller

Introduction

In previous post I described how to create a Microsoft Installer package with the WIX framework and how to create managed custom actions for an installer created with WIX.

We are distributing our products to clients having different environments. Most often there is no dedicated full-time network administrator or DBA available on client side. Thus our product installer has to account for this fact.

Currently we define our prerequisites for a successful installation to be either a Windows 2003 Server with IIS 6 or a Windows 2008 Server with IIS7. Both 32 Bit or 64 Bit versions of the OS are supported. We do NOT install a database but expect that either a Oracle Database Server or a MS SQL Server is available at the client side inside which our database will be hosted.

Since our application is based on the .NET framework our installer needs to be able to install .NET if required. A standard Microsoft Installer Package (MSI) cannot do this thus we need a bootstrapper application.

Unfortunately the WIX framework does not yet contain such a bootstrapper application. It was planned to release one with WIX 3.5 but it has been postponed to version 4.0

There are different ways how to create a bootstrapper for an MSI package. One is described here, its provided by the ClickOnce deployment features in Visual Studio. Another approach is to use dotNetInstaller, an open source project. This is the approach we chose for our product. What is dotNetInstaller? On its website it is descibed as

dotNetInstaller is a widely used, general-purpose setup bootstrapper for Microsoft Windows 95, 98, 2000, XP, 2003, Vista, 2008 and Windows 7.

dotNetInstaller enables the developer to define the application prerequisites and install the correct version(s) of these components in a predictable order based on the processor architecture, user operating system type and language, allow the user to download these components from the web, install these components directly from a single packaged setup, local media or both. …

Again documentation about dotNetInstaller is sparse like in many other open source projects. Luckily there are some samples contained in the package.

Creating a configuration file

To create a new bootstrapper we can use the GUI editor InstallerEditor.exe. But for maximum control and better understanding I prefer to manually edit the necessary xml configuration file. The basic layout of the schema is as follows

<?xml version="1.0" encoding="utf-8"?>
<configurations lcid_type="UserExe" ...>
    <schema version="1.9.5931.0" generator="dotNetInstaller InstallerEditor" />
    <configuration dialog_caption="ACME Product Installer" ...>
        <component command="..." ...>
            ...
        </component>
    </configuration>
</configurations>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

To require installation of .NET framework 3.5.1 if not already present on the target system we can add the following check to the component node

<installedcheck path="SOFTWAREMicrosoftNET Framework SetupNDPv3.5" 
        fieldname="Version" 
        fieldvalue="3.5.30729.01" 
        fieldtype="REG_SZ" 
        comparison="version_ge" 
        rootkey="HKEY_LOCAL_MACHINE" 
        wowoption="NONE" 
        type="check_registry_value" 
        description="Installed Check" />

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

this basically tells the bootstrapper to scan the registry for a Version key in the registry with a value greater than or equal to “3.5.30729.01”. The key is expected to be found at this location

HKLMSOFTWAREMicrosoftNET Framework SetupNDPv3.5

If we do not find this key we assume that .NET framework 3.5.1 is not installed and we want to download it from the internet. We put the following <downloaddialog> node inside our <component> node

<downloaddialog dialog_caption=".NET Runtime 3.5 SP1 - Download Components" 
                dialog_message="Press 'Start' to download the .NET Runtime 3.5 SP1" 
                dialog_message_downloading="Downloading installer ..." 
                dialog_message_copying="Copying ..." 
                dialog_message_connecting="Connecting ..." 
                dialog_message_sendingrequest="Sending request ..." 
                autostartdownload="False" 
                buttonstart_caption="Start" 
                buttoncancel_caption="Cancel">
                 
    <download componentname=".NET Runtime 3.5 SP1" 
              sourceurl="http://go.microsoft.com/fwlink/?linkid=118076" 
              sourcepath="#APPPATHdotnetfx35.exe" 
              destinationpath="#TEMPPATHdotNetRuntime_Download_#PID" 
              destinationfilename="dotnetfx35.exe" 
              alwaysdownload="False" 
              clear_cache="False" />
 
</downloaddialog>

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

The important part here is the attribute sourceurl of the <download> node which should point to the correct url. This could be a location on our own server which contains the .NET framework but it is preferable to download it directly from Microsoft. The correct address can be found out by trying to manually download the said component and copying the url from the browser.

Creating the bootstrapper

Once we have prepared our configuration file we can create the bootstrapper. To do this we use the linker provided by dotNetInstaller. A typical command looks like this (note that the following command has to be on one single line and has been reformatted here for readability)

pathToDotNetInstallerInstallerLinker.exe 
        /Output:Setup.exe 
        /Icon:ACME.ico 
        /Splash:splash.bmp 
        /Banner:banner.bmp 
        /Template:dotNetInstaller.exe 
        /Configuration:Configuration.xml 
        /Embed+

.csharpcode, .csharpcode pre
{
font-size: small;
color: black;
font-family: consolas, “Courier New”, courier, monospace;
background-color: #ffffff;
/*white-space: pre;*/
}
.csharpcode pre { margin: 0em; }
.csharpcode .rem { color: #008000; }
.csharpcode .kwrd { color: #0000ff; }
.csharpcode .str { color: #006080; }
.csharpcode .op { color: #0000c0; }
.csharpcode .preproc { color: #cc6633; }
.csharpcode .asp { background-color: #ffff00; }
.csharpcode .html { color: #800000; }
.csharpcode .attr { color: #ff0000; }
.csharpcode .alt
{
background-color: #f4f4f4;
width: 100%;
margin: 0em;
}
.csharpcode .lnum { color: #606060; }

this command as a result creates an exe called Setup.exe whose icon is ACME.ico. During creation the linker uses the information found in the Configuration.xml file. The MSI package is embedded in the Setup.exe since we use the /Embed+ command line switch. During startup of the Setup.exe the splash.bmp will be shown in a splash screen. When the first dialog is displayed it will contain the banner.bmp as a banner.

Running the bootstrapper

When the bootstrapper detects that the .NET framework isn’t installed on the target system the user is asked to first download and install .NET.

image

Windows 2008 Server

Windows 2008 Server does not allow for an explicit installation of the .NET framework (3.5.1 SP1 in our case). During installation of the framework an error dialog appears telling the user to install the .NET framework by adding a role to the server. The setup is then aborted.

image

Related Articles:

Post Footer automatically generated by Add Post Footer Plugin for wordpress.

About Gabriel Schenker

Gabriel N. Schenker started his career as a physicist. Following his passion and interest in stars and the universe he chose to write his Ph.D. thesis in astrophysics. Soon after this he dedicated all his time to his second passion, writing and architecting software. Gabriel has since been working for over 12 years as an independent consultant, trainer, and mentor mainly on the .NET platform. He is currently working as chief software architect in a mid-size US company based in Austin TX providing software and services to the pharmaceutical industry as well as to many well-known hospitals and universities throughout the US and in many other countries around the world. Gabriel is passionate about software development and tries to make the life of developers easier by providing guidelines and frameworks to reduce friction in the software development process. Gabriel is married and father of four children and during his spare time likes hiking in the mountains, cooking and reading.
This entry was posted in bootstrapper, How To, installation, WIX. Bookmark the permalink. Follow any comments here with the RSS feed for this post.
  • John

    hi experts. i want to know few things as i’m trying my hands in vb.net application development.
    1) What is a bootstrapper, how does it help us?
    2) I’ve built an vb.net application and now i want to deploy it in client’s machines. I’ve used SQL server 2005 as backend and MS Access 2003 for printing report(somehow logically).Now i want to incorporate both sql server compact edition and MS Access 2003 in the setup file i.e: when i install my project/software into client’s system, it will first install full SQL server and MS Access if they are already not installed, and then my application. how do i do that?

    If possible Please send Your replies to my mail Id- “jumba_4u@yahoo.com”. Please experts, let me know in detail if possible, thank u in advance, God bless u all.

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @John: a bootstrapper is an application that installs the pre-requisites on the system needed by the installer package which then in turn installs the application. In our case this might be the .NET framework which needs to be installed such as the application can run on the system.
    Visual Studio offers the possibility to create bootstrappers for SQL Server and IIRC for the JetEngine which is the database engine of Access. Just have a look at the installer template

  • Sunil Agarwal

    Hi..
    I am using the same code and am able to create bootstrapper. But when I provide icon parameter it fails throwing error
    Embedding icon “D:\Bootstrapper\dotNetInstaller 2.0\Bin\icon.ico”
    16×16, 16×16, 32×32, 32×32, 48×48, 48×48
    ERROR: The system cannot open the device or file specified

  • http://www.lostechies.com/members/gnschenker/default.aspx Gabriel N. Schenker

    @Sunil: you should post your question to the appropriate discussion group at http://dotnetinstaller.codeplex.com/

  • Nitin

    Good Article. however when I tired, came up with one minor problem.
    I was trying to play with dotNetInstaller bootstrapper for one of my project for installing some prerequisites. I run the command InstallerLinker and link my msi with banner and other stuff. The executable created a setup file named Setup.exe. I double click it install it and all went well.Now, when I hover the cursor over Setup.exe, I can see the company name is “DevAge, Vestris Inc. & Contributors”.Since I am delivering the project to the client, my client want their company name in place of it.Is there any way I can do it? If yes please explain in detail.Thanks,Nitin

    • Anonymous

      For any detail question regarding the dotNetInstaller please consult http://dotnetinstaller.codeplex.com/. There is a discussion section where you can post your question.