Join the Installation Revolution

by Michiel de Bruijn

Reprinted with permission from Visual Basic Programmer's Journal, 7/98, Volume 8, Issue 8, Copyright 1998, Fawcette Technical Publications, Palo Alto, CA, USA. To subscribe, call 1-800-848-5523, 650-833-7100, visit www.vbpj.com, or visit The Development Exchange

Microsoft's latest installation tool, Active Setup, redefines the way setup programs work. How will this affect you?

Since the advent of Internet Explorer 4.0 (IE4), most Microsoft products use Active Setup, a new installation program. End users appreciate Active Setup's new interface, a modest status window that replaces the way previous setup programs hogged the entire screen. Many users also like the heavy emphasis on downloading all or part of the installation payload from the Internet.

Active Setup is changing user expectations about setup programs—including yours. So you need to find out how Active Setup works, and how its changed setup paradigm affects you. Unfortunately, Active Setup hasn't been released for general use; at present you're limited to experimenting using Microsoft products that support it. Still, the code presented here should give you a good idea of what it's all about.

To begin with, Active Setup is Microsoft's trusted Acme setup engine (used for VB, Office, and most other products) rolled into an ActiveX component. As with Acme, you'll find an STF file in a proprietary Microsoft file format and CAB files containing the actual installation files. Together these drive the whole process. In fact, you won't find a standalone executable housing the setup engine.

Active Setup has no specific knowledge about how to install a particular product. Instead, it relies on an external process I call the setup implementation. Together, Active Setup and its implementation drive the installation, using properties and methods. They also respond to the events being generated.Because it uses functionality preinstalled on the target system to do its job, the setup implementation can be relatively small. If you're distributing the application on disk, the reduced overhead might reduce the number of disks needed. With online distribution, a smaller initial setup module means less time downloading. And you don't have to install one big monolithic file containing all possible application functionality. You can split an app into multiple modules, so users can download only the modules needed.

You can create the setup implementation using VB or any other ActiveX-compatible environment, such as IE4 or even Microsoft Word or Excel. If you use IE4, you can also easily preload the VB runtime files and consequently bootstrap a setup app written in VB. Plus, you can quickly generate a setup user interface with some HTML code and client-side scripting and change it at will, because the interface code resides on your own Web server. Microsoft is actively using this capability on its Web site to enable downloads of IE4 add-on functionality, as well as other products, such as the NT4 Option Pack.

A Web-based approach also lets you transplant your setup application to a CD. Using a Microsoft-supplied tool, you can map the directory structure of the CD into IE4's URL address space, and execute the setup from the CD as if it were running from the Web.

look for an activex wrapper

Third-party vendors are free to emulate Microsoft and create an ActiveX wrapper for their setup engines. Microsoft itself doesn't currently have an Active Setup SDK, but it's looking into the possibility. However, considering this approach's advantages, I wouldn't be surprised to see comparable Active Setup implementations from the makers of the Wise Installation System (http://www.wisesolutions.com), InstallShield (http://www.installshield.com), Inner Media (http://www.innermedia.com/html/product_info.html), and others, in the future.

Such third-party implementations would most likely obviate Microsoft's requirement that you use IE4 to host the Active Setup module, and would instead offer plug-ins for Netscape, or even a Java applet for use on any Java-enabled browser.

But until these alternatives appear, and to help prepare for their advent, you should look closely into Active Setup now. If you're not running IE4 already, you need to install it. Unless the Department of Justice decides otherwise, Active Setup will be a basic service in Windows 98 and NT5, because IE4 will be an integral part of those operating systems.

The Active Setup architecture is distributed across three kinds of files on the setup server or other distribution medium: CAB files for the setup payload; CIF files for component information; and EXE/INF/HTML files for setup implementation (see Figure 1). You can create the setup payload using the same tools you would currently use for that purpose. The setup implementation files (either an EXE file or some HTML containing client-side scripts) should be familiar; if you use an INF file to let Windows itself drive the installation process, you'll find that file format unchanged as well.

Figure 1: The Active Setup Architecture. In Microsoft's Active Setup scheme of things, the user first downloads the setup implementation, in the form of either an executable file, a client-side VB/ECMA-script, or an INF file (that can be processed by the OS). This implementation is then responsible for setting up and monitoring the operation of the Active Setup engine; the actual actions performed by the engine are determined by the STF file that forms part of the setup payload.

The other file format for your setup servers, the Cabinet Information File (CIF), is specific to Active Setup. The format is only semidocumented in an article on the Microsoft Developer Network (http://premium.microsoft.comtechart/msdn_actsetup.htm), written by Nancy Winnick Cluts. The tables in this article extend that information considerably, based on my actual experience with Active Setup. Documentation for the CIF format is supposed to be available in the Internet Client SDK, but I could only find some minor fragments of it.

You use a CIF file to describe the various components that make up the application you want to install. In addition to one or more mandatory base components, you'll typically include one or more optional modules (see Listing 1 for an example of a CIF file; see Table 1 for the individual keywords).

[Listing 1] VB5
[Version]
Signature=$Chicago$
DisplayName=VBPJ Active Setup Example
;Require 10MB of free space to start
MinFileSize=10000
[BASE_VBPJ]
DisplayName=VBPJ Sample Main Module
GUID={guid-goes-here}
URL1="setupvbpj.cab",3
Size1=1417,1430
Command1="vbpjsetup.exe"
Type1=2
Version=1,00,1234,0
Reboot=1
InstalledSize=980,524
[OPT_VBPJ]
DisplayName=Optional Module
GUID={guid-goes-here}
URL1="vbpj_opt1.cab",3
Size1=774,787
Command1="vbpjsetup.exe"
Switches1="/addopt:1"
Type1=2
InstalledSize=1320,0

Listing 1: Describing the Setup Components. This example Component Information File (CIF) tells Active Setup which modules the installation contains, where to find the payload for them, and how to handle the actual setup process. The file format is currently undocumented, and you'll find plenty of interesting additions to the keywords listed in Table 1 in actual CIF files.

[Table 1]

Directive(s) Purpose
[ComponentID]Starts the definition section for a named component, such as BASEIE40_NTx86.
DisplayName= string
GUID={GUID}
Defines the friendly name for the component; for example, "Internet Explorer 4.0 Web Browser." For easy localization, use a variable name between percent signs. This value will be retrieved from the CIF's [Strings] section. The Globally Unique Identifier (GUID) value is used by Active Setup to determine if the component is already installed on the system.
Version= verinfo
InstalledSize= progsize, winsize
Supplies the component's version information (in standard major, minor, build, or revision format) as well as the amount of bytes the component takes up in the application and Windows directories, respectively.
URLn=URL, flags
Sizen=size,ondisk
Downloads a file from the specified URL, which can be of type file, http, or ftp. More than one URL can be specified per section, such as URL1, URL2, and URL3. The size parameter indicates the real size of the CAB file; "ondisk" indicates the impact on the user's free disk space, although this doesn't always seem to be implemented consistently.
The flags specify the desired processing after the download is complete:
1 – Extract items from the CAB file.
2 – Consider the URL as relative to the BaseURL specified by the setup implementation (see Table 2).
4 – Delete the CAB file after processing.
Commandn= string
Switchesn= string
Typen= enum
Specifies the command to be executed after downloading and processing the CAB file from the corresponding URL. The Switches directive contains the command-line parameters for this process, and the Type directive (0=INF; 2=WinExec) indicates the type of command.
Dependencies= component Declares component to be a dependency of the current component and instructs Active Setup to install it if not already present. Appending :N to the component identifier makes the setup fail, rather than complete.
UninstallKey= string
SuccessKey= string
ProgressKey= string
Specifies the unqualified registry key name to which you write uninstall, success, and progress information, as well as (optionally) the value of that key.
Reboot= boolean Indicates whether the dreaded "Setup must restart your computer" dialog will always be inflicted on the user (if False, you only need a reboot if one or more destination files were in use).

Table 1: Directives Used in the Component Information File (CIF). Although a crucial (and unique) part of Active Setup, the CIF file format is only semidocumented in a Microsoft Developer Network article. The CIF file describes the components (such as CAB files) that comprise the installation, as well as the commands used to process them. A third-party supplier of an alternative Active Setup module would most likely supply its own file format for this purpose.

Once the Active Setup engine has processed the CIF file, it's ready to start the real work. This work is driven by the setup implementation through the properties and methods exposed by Active Setup (see Table 2).

[Table 2]

Property/Method Description
AbortHalts the installation in progress, returning a status code to the Active Setup component.
BaseURLSets the base URL to be used to resolve relative URLs specified in the CIF file.
CheckFreeSpaceChecks for sufficient disk space to process the current CIF file (the process involves downloading the CAB files and performing the subsequent "real" installation.
DownloadDir Specifies the (temporary) download directory for CAB files.
EngineStatus Returns the status of the Active Setup engine:
0 – Not ready, no CIF file specified.
1 – Busy, CIF download in progress.
2 – Busy, installation in progress.
3 – Ready for further actions.
FinalizeInstallInvoked at the end of the installation, this method notifies users and reboots the PC if needed.
HandleEngineProblemSpecifies how to handle a condition that caused the OnEngineProblem event to be fired (see Table 3).
IsComponentInstalledChecks specified component by its ID (aka CIF section name) to see if it's already installed. Possible results:
0 – Not installed.
1 – Already installed.
2 – An older version is already installed.
3 – User-declined version scan.
ProcessesComponentsProcesses current CIF file and installs all files in the associated CAB files. Flags can control Active Setup's behavior during this phase:
1 – Don't reboot (handy for multicomponent installs).
2 – Don't show installation progress.
4 – Don't show setup summary.
ReadyState Indicates whether the control is ready to accept commands:
0 – Not ready.
4 – Ready.
SetActionSpecifies how the specified component ID should be handled when the CIF file is processed:
0 – Skip this component.
1 – Install component (default).
2 – Uninstall component.
SetCifFileSets the name of the CIF file to be used.
TotalDependencySizeReturns total size (in bytes) of all components.
TotalDownloadSizeReturns total size (in bytes) of CAB files to be downloaded.

Table 2: Talking to the Active Setup Component. Apart from initializing the Active Setup engine and monitoring its status, Active Setup's methods and properties are used to initiate the high-level functions of any setup program: component selection, checking for free disk space, and the actual file-copying process.

For a simple full install, you only need to set the BaseURL and CIF properties, and invoke the ProcessComponents method. If you want to select which components get installed—or even perform a (partial) uninstall—you need to add some minor modifications to your current IE4 setup (for an example, see Listing 2). The sample I developed leaves error handling in your capable hands, and uses VB's debug output window as its main user interface; but it should give you a pretty good idea of how things work.

[Listing 2] VB5

Private Sub SampleInstall()
With InstallEngineCtl1
   '//Set base URL for the install (the NT version of
   '//IE4, in this case)
   .BaseUrl = _
      "http://www.microsoft.com/ie/ie40/download/" & _
      "rtw/x86/en/download"
   '//Or, if you happen to have the IEAK:
   .BaseUrl = "file:///C:/Program%20Files/IEAK/download/en"
   '//Specify our CIF file and the CAB file that's in
   .SetCifFile "ie40cif.cab", "ie40.cif"
   '//Wait for CIF to start loading
   While .EngineStatus = 0
      DoEvents
   Wend
   Debug.Print "Loading CIF file -- please wait"
   '//Then wait for loading to finish
   While .EngineStatus = 1
      DoEvents
   Wend
   '//Check Active Setup status
   If .EngineStatus = 3 Then
      Debug.Print "CIF file loaded OK!"
   Else
      Debug.Print "Oops, failure to load CIF file"
      Exit Sub
   End If
   '//Check if Microsoft Wallet is installed
   If .IsComponentInstalled("ActivePayment") Then
      '//Flag component for uninstallation
      Debug.Print "Removing component..."
      .SetAction "ActivePayment", 2
   Else
      '//Flag component for installation
      Debug.Print "Installing new component..."
      .SetAction "ActivePayment", 1
   End If
   '//And start the actual install
   .ProcessComponents 0
   '//Wait for installation to finish
   Debug.Print "Installation in progress..."
   While .EngineStatus = 3
      DoEvents
   Wend
   While .EngineStatus = 2
      DoEvents
   Wend
   Debug.Print "Done!"
   
End With
End Sub

Listing 2: A Minimal Active Setup Implementation. The code here uses the setup information for Microsoft Internet Explorer 4.0 to initialize Active Setup and to install the Microsoft Wallet component (if the component is already present, it will be uninstalled). Simple as it is, this routine is a fully functional Active Setup implementation, although it totally ignores error handling.

After the ProcessComponents method has been called, the setup implementation can pretty much sit back and relax. Unless you instruct it otherwise, the Active Setup module indicates installation progress through its own user interface, telling the setup implementation what's going on through a series of events (see Table 3). Such events provide sufficient information for the setup implementation to stay fully in control of the installation. For a software package with multiple online download sites, for example, you can configure the setup implementation to restart the installation with a failover to a different download site from the default site. With custom coding you can add smooth handling for unexpected events, such as a full disk.

[Table 3]

Event(s) Description
OnCheckFreeSpace Used by Active Setup to report the amount of disk space available in the Install directory, Windows directory, and Download directory, as well as the fully qualified paths for these locations.
OnEngineProblem This event is fired when you get a temporary or fatal error that needs to be handled by the setup implementation (typically a choice between retrying the current operation or aborting the installation).
OnEngineStatusChange
OnReadyStateChange
Invoked whenever the EngineStatus or ReadyState property changes to allow the setup implementation to update its display. Both methods also report an undocumented substatus value.
OnProgress Called with the percentage of installation completed, as a parameter, whenever that value changes.
OnStartComponent
OnStopComponent
These events indicate the beginning and end of a component's installation. They also report full status information about this phase of the setup process.
OnStartInstall Fired respectively at the start and end of the complete installation, using information about the size and status of the installation as the parameters.

Table 3: Active Setup's Events. At the start and end of each stage of the installation process, Active Setup fires an appropiate event to inform the setup implementation of its new status, and lets it update its display accordingly. Exceptions, such as a full disk, are reported through the OnEngineProblem event.

All in all, Active Setup is quite compelling, both for yourself and for your users, who get a streamlined and efficient setup process. Even when using a third-party setup tool, you get much more control over the installation, and you get to write the code in the language you know best: VB. It will definitely pay to familiarize yourself with Active Setup now, and to start thinking about how you'll use the non-Microsoft implementations as soon as they appear.


Download the code for this article here