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 months column Im 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. Its
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 youre not in the habit of
rolling your own setup1.exe then its 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 wont 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 well 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 cant 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 doesnt 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 isnt 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. Its 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. Ive 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
Ive 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. Ive 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, dont 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.