Monday, 08 September 2008
PicoSearch

Distribution Issues

This column appeared in the March 1999 issue of EXE. It discusses the Package and Deployment Toolkit, InstallShield, testing setup programs, and installation prerequisites.


Developers who used to use version 3 of Visual Basic might well remember the first implementation of the setup wizard. Although it was supposed to be a Windows application it would spawn DOS windows when it ran the command-line file compression utility which gave the impression of a rather Heath Robinson implementation. Furthermore it was notoriously buggy. The setup wizard has undergone some major facelifts since this time, but has now been superseded in Visual Studio 6 by the Package and Deployment Wizard (PDW). In this month’s column I’m taking a look at some of the issues around application and component installation.

Since the advent of ActiveX technology the steps that go into the installation of an application or a component are somewhat more involved. Gone are the days when a few files can just be copied onto the hard disk. Anything that exposes an ActiveX interface must be registered, applications must be given shell links, and care must be taken to ensure that all required files or subsystems are also present – something that cannot be taken for granted. Furthermore there are components that are destined for an Internet environment, which of course requires a somewhat different installation approach.

Setup.exe, the program that is launched during a typical application (i.e. non-Internet) installation, is chiefly responsible for ensuring that the core Visual Basic runtime files are installed. It’s possible that earlier versions of some of these files might already exist on the machine, in which case a reboot will be required to complete the replacement and allow these new files to be loaded. Setup.exe then passes control over to setup1.exe. As with previous setup wizards a default setup1.exe is provided, although it can be replaced with a customised version built from the supplied Visual Basic source project. Setup.exe and setup1.exe use a parameters file – setup.lst – which lists all of the files that need to be installed, and also where they should be placed. The setup1.exe program makes use of an additional library file called vb6stkit.dll which provides several useful pieces of functionality. If you’re not in the habit of “rolling your own” setup1.exe then it’s still worth having a look through the source code for the underlying project because there are quite a few routines that could well come in useful for other projects.

Each file is installed via the VerInstallFile API. This function checks the version number of a file to be copied and, if it finds a file of the same name in the destination target, confirms that the replacement file is actually newer. For this reason it is important to increment the version number of a component when it is modified – an updated file with the same version number won’t necessarily be copied over the existing file. The VerInstallFile API is also capable of decompressing the file if necessary.

Files that are installed into common areas, such as the Windows directory, are generally treated as shared files, that is they can be used by different applications. For each shared file a usage count is stored in the registry under

\HKEY_LOCAL_MACHINE
 \SOFTWARE
  \Microsoft
   \Windows
    \CurrentVersion
     \SharedDLLs

When an application is installed the VerInstallFile API increments the usage count for each component that is used. This usage information is generally provided by dependency files, which we’ll come back to a little later.

Windows logo compliance

As a means of guaranteeing to the user community that any given application behaves in a manner consistent with previous experience, Microsoft supports a Windows Logo program. While this can’t be enforced, it provides a form of certification for third-party software companies by allowing the display of the “Designed for Microsoft Windows NT and Windows 95” decal. In order to earn this certification a software release must be verified by an authorised testing centre as conforming with certain implementation specifications. Apart from core specifics, such as “it must be true 32-bit code”, the logo program states certain expectations about the installation of the application. The setup program for the application must itself be a 32-bit, Windows-based (i.e. graphical) utility. Furthermore, it should detect at runtime the version of Windows that it is running on, and install the correct version of the application (if appropriate) automatically.

One of the facilities that Microsoft are also keen to push in this area is the use of the AutoPlay facility when dealing with CD-ROM installations. When a CD-ROM is placed in a drive Windows will detect the change of state, read the file list of the root directory, and search for a file called autorun.inf. These files are normally very small and simple, and basically provide the name of an executable that should be run in order to provide the master application setup routine. Once the application has been installed it is then up to the third-party developer to decide whether subsequent loading of the CD-ROM will display anything.

Another important requirement is the provision of an uninstaller. When the PDW installs an application or component it also copies a file called st6unst.exe into the Windows root directory if it doesn’t already exist, and an installation log file called st6unst.log into the application directory. This log file contains information such as the directories that were created for this installation, the registry entries that were made, and the shell links that were created. The setup program then registers this application removal facility into the list of applications that are shown within the Add/Remove Programs applet in the Control Panel. This information is stored at

\HKEY_LOCAL_MACHINE
 \SOFTWARE
  \Microsoft
   \Windows
    \CurrentVersion
     \Uninstall

and, for each registered application, contains two pieces of information: the display string for the Add/Remove Programs applet, and the command line to execute to start the uninstallation. By the way, st6unst.exe will complain if you attempt to run it as a standalone application.

When something is uninstalled, the usage count on any shared components should be decremented by a value of one. If, after this has happened, the usage count has dropped to zero then the application may decide (possibly by asking the user) whether to actually delete these files. This process does contain a couple of caveats however. First of all, the usage count decrement should never let the value fall below zero. This could lead to a problem at some future time where a component that is still needed is inadvertently deleted. The second stipulation is that this usage count decrement should not be applied to what Microsoft refer to as “core components, in particular Microsoft Foundation Class Library (MFC) DLLs, as well as ODBC and DAO DLLs”. Microsoft maintains a formal list of all such files at http://msdn.microsoft.com/developer/winlogo/downloads.htm.

Packages and dependencies

The earlier setup programs used to compress each file in an installation kit and then expand it again as it was copied over onto the target machine. Nowadays groups of files are collected into packages. A package can be of two types: a standard package is intended for distribution via floppy disk, CD, or network share, whereas an Internet package speaks for itself. Both types of packages contain one or more files collected together into structured storage files with a .cab extension (short for ‘cabinet’).

The PDW isn’t solely concerned with creating application packages; it also creates dependency files. These files exist for reference purposes and catalogue certain information about components or applications. Listing 1 shows the pertinent part of the dependency file that is supplied along with the richtx32.ocx control (dependency files have the same name as their code-counterparts, but with a .dep extension). The information in listing 1 shows that it is dependent upon the riched32.dll and comcat.dll files also being present in order to run. This information is stored within the OCX itself, but is extracted into a handy reference format by the PDW. When a package is being created a master list of dependencies can then be compiled to ensure that all required files are included in the setup package.

[RichTx32.ocx]
Dest=$(WinSysPath)
Register=$(DLLSelfRegister)
Version=6.0.81.69
Uses1=RichEd32.dll
Uses2=ComCat.dll
Uses3=
CABFileName=RichTx32.cab
CABDefaultURL=http://activex.microsoft.com/controls/vb6
CABINFFile=RichTx32.inf

[ComCat.dll]
Dest=$(WinSysPathSysFile)
Register=$(DLLSelfRegister)
Uses1=

[RichEd32.dll]
Dest=$(WinSysPathSysFile)

Listing 1: Dependency information for RichTx32.ocx

Visual Basic itself comes with a somewhat larger dependency file called vb6dep.ini which stores the dependency information for the entire development environment. When the PDW runs it also looks in this file as well as individual dependency files in order to resolve all dependencies. If it cannot do this then there is no guarantee that an additional, unidentified file will not be required by the application at runtime and so might fail. When this happens you get a warning and can decide the best course of action to take.

Installation prerequisites

If your project is using ADO then the PDW will also bundle in an additional install program called mdac_typ.exe. This program checks whether the ADO libraries, and the underlying OLE-DB subsystem, have already been installed and, if not, will do so. A copy of this program is installed into the Wizards\PDWizard\Redist directory of the Visual Basic installation, and is transferred from there into PDW-generated setup packages. It’s worth keeping an eye on the download site for this file (http://www.microsoft.com/msdownload/uda/mdac_typ.asp) as Microsoft update it from time to time. If this installation program is applied against a Windows 95/98 target then you will also need to provide the Distributed COM installation routine. This also ships with Visual Studio, but is additionally available from http://www.microsoft.com/com/dcom.asp.

Testing a setup routine

When a setup routine is created, it should of course be tested. I’ve already written a fair amount of material on this subject in the book (see biog at end of column), some of which will be relevant background reading for this section topic. Since I wrote the last edition of my chapter I’ve set up for myself a very efficient test environment for my own work. My notebook computer has removable hard disks, which means that I can maintain separate environments on different disks. I’ve dedicated one such disk for testing purposes. On this disk I use a product called Drive Image which is designed to store a compressed copy of a partition on another partition, or on some other media such as a Zip disk. Using this concept I have backups of a clean basic Windows NT 4 installation, another Windows NT4 installation that has also had the full IE4 installed, a clean copy of Windows 98, a Windows 2000 beta, and so on. Using Drive Image I can restore a backed-up copy of my target platform within a couple of minutes and can thus be sure of installing into virgin territory. This is an excellent way of ensuring that you have not omitted any key files that would probably be present on your development machine anyway. When you perform your regular builds (you DO perform regular builds, don’t you?) you also get the opportunity to ensure that your setup program also gets checked for correctness.

Other tools

Although the PDW is a competent deployment utility, it does still have a few shortcomings. The ability to modify the setup1 source files provide a means of overcoming this, but a more elegant solution can be to use one of the third-party utilities for the creation of setup programs. InstallShield Express provides a graphical approach to the creation of slick-looking installation routines that have more flexibility than the PDW. For example, the ability to add custom registry keys, to spawn external programs (such as the ADO installer mentioned earlier), or to create different setup types (e.g. Complete and Minimal) are very straightforward. The big brother product to this, InstallShield Pro, offers everything that InstallShield Express does but also includes a powerful scripting language for more complex installations.

Copyright ©2002 Jon Perkins I, Jon Michael Perkins, hereby assert and give notice of my right under section 77 of the Copyright, Designs, and Patents Act 1988 to be identified as the author of the foregoing article.