Customizing VB6 Setup1.exe - noSE Version - Package and Deployment Wizard (PDW)
NOTE:
This file contains explanation and directions for using the included Setup1 Demo Project
to easily build graphically unique, customized installers for each of your VB6 programs.
The Setup1 Demo Project is a remake of the PDW Setup1.exe file. This version adds
several new functions, is much more compact, and does not require Setup.exe. (noSE version stands for "no Setup.Exe".)
Updated 8-15-2006
Introduction
The Package and Deployment Wizard (PDW) creates setup packages for VB6.
Setup1.exe is the executable that the PDW uses for installation. The PDW normally creates
a setup with 3 files (assuming there is a single CAB file):
setup.exe is the
"bootstrap" file that starts the install. The
ProgramName.CAB file contains the program files and
Setup1.exe, which is the actual installer.
setup.lst is an ini file that holds
install information needed by setup.
When a PDW
setup is run, setup.exe extracts Setup1.exe from the setup CAB file, moves
it to the Windows folder (?), and runs it with a command line that tells Setup1.exe
where to find the other files: the CAB and setup.lst. Setup1.exe then takes over from there.
Setup1.exe is written in VB6 and the Setup1 project is included
in a VB6 install. In fact, not only is the Setup1.exe code available, but it also
contains numerous commented notes to provide some guidance to anyone who
wants to edit the code.
In the
Wizards\PDWizard folder you should find the
Setup1
project folder, a copy of
Setup1.exe, a copy of
setup.exe, and a file named
VB6DEP.INI.
(You will need to deal with those 3 files when building custom setups with VB's Setup1 project,
but they are not needed for this noSE version.)
The Setup1 Demo Project that goes with this help file is a rewrite of the
version that comes with VB6. It has been "weeded" of confusing and redundant code
and several rarely-used functions have been removed, such as remote install option, silent
install option, etc. This is, obviously, one version of how Setup1.exe could be written.
You may want to use the project as-is or you may just want it for reference in
writing your own version. Either way, most of the information in this file will be relevant.
What is in This File?
In order to customize a PDW setup one needs to know the basics of how the PDW works.
This file explains those details and provides a step-by-step guide, "soup to nuts", for
anyone who wants to create their own custom setups.
NOTE: This help file is specific to the noSE version of the custom Setup1 code.
Back to Index
Differences in This Version of Setup1
This version of Setup1 has been cleaned and several optional
functions have been removed in order to simplify and shrink the resulting
executable.There have also been functions added. The resulting EXE is about
half the original size.
Weeding done in this Setup1:
If you have looked at the original Setup1 code you may have
noticed that it seems unnecessarily bloated, convoluted and confusing.
For example, the functions
MakeLongPath, GetLongPath and
LongPath
are all pointing to each other! Another example: With variables in the functions to determine whether
an installing file should overwrite the existing version,
owYes means "No,
don't overwrite, the file is not newer" and
owNo means "Yes, overwrite
the old file".
In other places several redundant variables are created, apparently to
signify different details about the content of the variable. For example, the
variable
SrcFile might hold the path of a file to be installed. Then if
SrcFile
is moved to the TEMP folder the code might run something like:
TempFile = SrcFile
By the end of the function there might be 4 variables that are all holding the
same file path!
This version of Setup1 has been cleaned to remove redundant code
and rewrite confusing code. Many functions have been left mainly untouched. It's
still essentially the same Setup1, but the code has been simplified.
Some of the functions have been entirely rewritten in
order to clean them up. Others have been edited in an attempt to simplify
unnecessary complexity. Example: The function
IsSourceFileNewer was
returning a UDT variable, declared in the
FileComparison ENUM with 3
constants:
fcNewer, fcOlder and fcEquivalent. Yet equivalent gets the
same treatment as older in the code, so there is no purpose to it.
IsSourceFileNewer was therefore changed to a Boolean function for clarity
and the ENUM
FileComparison was removed.
Functionality removed from this Setup1
In the interest of simplicity, optional functions that are
rarely used have been removed from this version of Setup1. If you need
a specific function you may need to add it back in. The following
changes have been made in this Setup1:
- Silent install functions removed.
- Remote install functions removed.
- Special treatment for data access components removed.
- Does not write path value in registry for multiple apps.
(only used if setup.lst includes "AppPath" value in [Setup] section.)
- No ability to install from 2 or more drives.
- racmgr.exe, etc. functions removed.
- Installer must have only 1 CAB.
Functionality added to this version of Setup1
Graphics:
This version of Setup1 is designed for easy graphical customizing.
There are only 3 forms: The "Welcome" form, the form for changing selected install path,
and a progress bar form. There are built-in functions to create a color gradient on these
forms, if desired. The general design of this Setup1 makes it easy to swap out
logos and icons, colors and backgrounds, in order to create a customized, professional-looking
installer for each program being installed.
Shortcuts: Start Menu, Desktop and Quick Launch -
When you open the demo project you'll see that
frmBegin.frm
has 2 checkboxes, one for a Desktop shortcut and one for Quick Launch. If these boxes
are left checked during install then shortcuts will be created in those locations. The shortcut
creation will also be logged so that they can be removed at uninstall.
The PDW normally creates a shortcut and optional folder on the
Start Menu only. This version of Setup1 creates a shortcut in the All Users Start Menu\Programs
folder. Then it also provides the other two optional shortcuts. In accord with standard
practice, the Desktop shortcut is created on the All Users Desktop.
The way the code works is to first get the basic Desktop folder,
which is the right path for Win9x. Then, if the install is on NT, it tries to get the
All Users Desktop path. The result is that the shortcut appears on all Desktops, on all systems.
The Quick Launch
shortcut is created in the current user's Q.L. folder. (If it were created in the All Users
Q.L. folder Windows would not display it.)
Note that you can call the sub
AddShortcuts
additional times (or edit the sub) if you want to add multiple Start Menu icons.
Application Data Install option -
With the increasing use of multi-user WinNT systems like XP,
the Program Files folder is being used more for just the basic program binaries,
while the current user's App. Data folder is used for any configuration information
not kept in the Registry. The standard behavior established is that a company
subfolder is created in the App. Data folder, and that subfolder stays when the program
is removed. This approach will apparently be enforced in Vista, with access to the Program Files folder
requiring the highest level of security!
In order to accomodate these changes, this version of Setup1
has built-in functionality to 1) find the path of the user's App. Data folder,
2) install files to that folder during setup, and 3) leave those files during uninstall.
The PDW does not provide an App. Data option, but the setup.lst file can be edited
to provide the necessary information so that this version of Setup1 can automatically
create an App. Data subfolder and install all designated files there.
EULA clickthrough:
The Welcome form is set up with an EULA clickthrough.
Just insert an appropriate EULA for each build.
Add/Remove Update:
In Windows XP the Add/Remove applet displays
a program icon and program size for each installed program listed. That functionality
is relatively new. It was built into Windows Installer setups but is not part
of the PDW setup. This Setup1 includes an update to fix that. (While the icon
and program size are fairly useless additions to Add/Remove, if you do not provide
the size XP will "make a guess". It's not unusual for that guess to be wildly off.
So without this update your software listing in Add/Remove might say that the
program files take up 800 GB, or something similarly ridiculous.)
Back to Index
Step 1 - Edit Setup1
This Setup1 is designed for easy customizing. It's recommended that you
start by making a copy of the project, one copy specifically for each program. For example, if your
program is
ABC-Editor then copy the Setup1 project to something like "ABC-Editor Setup1".
Next, open the project and do the GUI work for the specific program: Change the
name and version labels in the Welcome form, select colors or backgrounds for the
forms, assign new icons, and insert an appropriate EULA in fWelcome. If you do not want to use
the color gradient background option then comment out the
ColorBack
sub in each
Form_Load. If you do want to use a gradient, edit
each
Form_Load call to
ColorBack,
specifying the colors you want. For convenience, the parameters are simple 6-character hex
strings with RRGGBB format, as in HTML.
In addition to the GUI update, do a search in the code for "
UNIQUE".
(All in uppercase.) That string marks areas where you may need to edit the code. For example, in
ModDeclares,
the constant
sSetup represents the title used in message boxes. That needs
to be adjusted for each specific program install.
See the
Notes section for important info. about editing the Setup1 project.
Back to Index
Step 2 - Compile the new Setup1 and run the PDW
After editing the project, compile a new Setup1. The name does not matter for this version of
Setup1. You can name it anything you like: Setup.exe, ABCEdSetup.exe, BlahSetup10.exe, etc.
In this noSE version of Setup1, Setup.exe is not used. The PDW cannot be made to
adapt to this setup modification. The package it makes will just have to be edited after creation.
So, the next thing to do after compiling a new Setup1 is to just run the PDW and let it do
things its own way, creating a new setup package.
Back to Index
Step 3 - Edit the setup.lst File Produced by the PDW
After creating a setup package with the PDW you should have
something like: ABC-Ed.CAB, setup.exe and setup.lst. There should also be a
folder named
Support.
There are two steps that need to be performed now: Edit the setup.lst file
and rebuild the CAB file. The package can then be assembled.
Edit the Setup.lst file:
Setup.lst is an INI file. With the noSE version of Setup1 some of the
values are no longer relevant, while some new ones must be added.
Open setup.lst in Notepad and make the following adjustments:
[Bootstrap] section:
SetupTitle, SetupText, Cabs and
Spawn - Remove these values. They are no longer used.
SetupText is what shows in the odd gray window that flashes at beginning of setup. That window
is created by Setup.exe, so it won't show with this version of setup because Setup.exe is not used at all.
Spawn is the name of the Setup1 executable that Setup.exe should extract
from the CAB. Again, there's no Setup.exe so
Spawn is not needed.
The
Cabs value is the number of CABs used in setup. There must be
only 1 CAB in this case, so the
Cabs value is not needed. (This Setup1 assumes
no floppy installs, so more than 1 CAB is not necessary.)
The other 3 values in
[Bootstrap] will stay.
Uninstal (st6unst.exe),
TmpDir
and
Cabfile are still used.
[Setup] section:
Title - Check this value. In the original Setup1 this is used as the
title along the top of the fullscreen blue window. That's not used here, but Title is
also the name for the program folder. The PDW may not have guessed the name that you want.
The other settings in
[Setup] will stay, but two or three
new ones must be added:
AppSize -
This is a new value, specific to this version of Setup1. AppSize
needs to be the total size of the installed software, in KB. Example:
AppSize=2320.
The AppSize value gets written to the Registry and is used in XP to show the program size
in the Add/Remove applet window.
AppRemIcon -
This is a new value, specific to this version of Setup1.
AppRemIcon is the icon that XP will display in the Add/Remove applet window. This value needs to be an icon
from a file in the program folder or a subfolder thereof. The program folder path (i.e. "C:\Program Files\ABC-Editor\")
will be concatenated with this value and written to the Registry by this version of Setup1.
An example for this value might be:
AppRemIcon=abc-ed.exe 0.
NOTE: If [Program Folder Path] + [AppRemIcon Value]
is an invalid path, your program may not be listed in Add/Remove.
AppDataName -
This is a new value, specific to this version of Setup1.
AppDataName is the name of a folder to create inside the current user's Application Data folder. If this value is missing
then any files set to install to App. Data will instead be installed to the program folder. If no files are to be installed to App. Data
then this value is not necessary. The AppDataName should be a unique company name, such as Microsoft. Mozilla, Adobe, etc.
Example:
AppDataName=AceAndAcme
[Bootstrap Files] section:
This section is no longer needed. It was the list of files
that Setup.exe was supposed to install before running Setup1.exe. Typically VB6STKIT.DLL
is here, but that will be dealt with by the new Setup1. If the VB6 runtimes were being
installed that would also be listed here, but the runtime must be already installed for this
Setup1 to work.
[Setup1 Files] section:
This section is not edited unless files are being installed to App. Data.
If you want to install files to an Application Data\YourCompanyName subfolder you must
first add the
AppDataName value (see above). Since
the PDW does not deal with App. Data, it does not matter what path you select for installation
when running the PDW. To have a file installed to an App. Data subfolder, edit the path
section of the file string as shown below:
File1=@filler2.txt,$(AppPath),,,7/27/06 11:42:20 PM,61,0.0.0.0
File2=@filler1.txt,$(AppData),,,7/27/06 11:42:08 PM,53,0.0.0.0
Notice that filler1.txt, the 2nd file, is set to install to
$(AppData).
If any of the above explanations are not clear,
see the setup.lst file included with the "Blah Program" sample installer. That installer,
blahsetup.exe is a self-executing zip file. If you rename it from ".exe" to ".zip"
most ZIP programs will be able to open it.
Back to Index
Step 4 - Rebuild the setup CAB File and Assemble Your Package
Now you have the updated setup.lst file, Setup.exe, the program CAB,
and the Support folder. The CAB needs to be rebuilt because you need some of the setup
files to be outside of the CAB during installation. It will be rebuilt without those files. Proceed as follows:
1) Copy your edited setup.lst into the Support folder, overwriting the one there, so that you don't risk having your version overwritten when you rebuild the CAB.
2) Open the project .DDF (text) file in the Support folder. Toward the bottom of that file, after
the last line that begins with ".Set", you should see a list of all files in the CAB - one per line.
Remove the following file names from that list if they appear:
VB6STKIT.DLL, ST6UNST.EXE and
Setup1.exe
(or whatever the name of the Setup1 executable is). Then save the changes to the DDF file.
3) Run the BAT file in the Support folder. That will cause MAKECAB.EXE to replace the
project CAB file, leaving out the files that have been removed from the DDF file list.
4) Three files will now need to be packaged outside the CAB in your setup package, along with the setup.lst file:
VB6STKIT.DLL (The setup "tookit" used by Setup1), ST6UNST.EXE (The uninstaller executable), and your
custom Setup1 executable.
5) You no longer need setup.exe, so that can now be deleted.
6) Ideally, the CAB and 4 files should now be packaged more neatly,
perhaps by putting them into a self-executing zip file. Either way, the setup is
now started by having the CAB and other 4 files in one place, and then running the
Setup1 executable. Since this version of setup does not use setup.exe, it does not matter how
long the Setup1 executable name is, or what the name is. The final collection of files going into the
package should be:
YourProgram.CAB (the CAB file)
YourSetup1.exe (the custom, noSE version, Setup1 executable)
VB6STKIT.DLL (DLL used by setup)
ST6UNST.EXE (VB6 Uninstaller executable)
setup.lst (setup INI file)
If using a self-executing ZIP package, put all 5 files into the zip,
set it to unload into the TEMP folder, and set it to run your Setup1 executable
after unloading. If a self-executing ZIP is not used, all 5 files will still, nevertheless,
need to be in the same location when install is run.
Back to Index
Step 5 - Test Install
Once setup.lst has been edited, the CAB rebuilt, and the setup package assembled,
test the installation. If there are any problems, check the steps above to make
sure that
1) you used the right version of your custom Setup1 executable,
and that
2) the values in setup.lst are valid.
Back to Index
Notes
Code comments: In almost all cases, where there are comments in the Setup1 code,
a plain apostrophe marks the original Microsoft comments. My own comments are marked by:
'--
Locked controls on forms:
A hidden property, LockControls, has been set in the original
Setup1 form files (but not in the files in this package). LockControls does
not show up in the properties window but it prevents controls from being
moved at design time. To unblock the original Setup1 project forms for
modification, open them in Notepad and remove the LockControls
property manually.
Type Libraries: There are two included type libraries that are
referenced in this project. The path will need to be changed in the VBP file
or the TLBs will need to be re-referenced:
VBSHELL.TLB - shows in References dialogue as: VB-friendly Shell interfaces
SHELLLNK.TLB - shows in References dialogue as: VB 5 - IShellLinkA Interface(ANSI)
PDW bug: As some people may be aware, the PDW's Setup1 code was originally written with
a bug in the function
SourceFileIsNewer. That function compares versions
of files when a file being installed has a version. If version cannot be found then it compares dates.
In the original code, the version check worked OK, but the date check had a typo causing it to
overwrite an existing copy of the file only if the pre-existing copy was
newer than the copy being installed.
It should have been written to overwrite the file only if it was *older*. This version of Setup1 fixes that bug.
Win2000/ME/XP installs: Windows 2000, ME and XP all have System File Protection enabled by default, which
prevents system files from being overwritten. According to Microsoft, main system files on these systems
should only be updated by official service packs. Since all 3 systems already have the VB6 runtime,
there are few system files that might be needed anyway. If a newer system file is shipped on these systems
the install is likely to loop, rebooting to install the system file, then needing to repeat the action after
Windows SFP puts back the old version!
In order to avoid install problems, system files should only be shipped for
Win95/98/NT4. The shipping version should always predate the same file on SFP systems.
Some of these files have been handled in service packs to VS/VB. If you look in the
Wizards\PDWizard\Redist folder you should see a number of files that have been put there
by service packs. The PDW will use those files rather than the version in the system folder.
For example,
MSVCRT.DLL (The VC++ runtime) should be in the Redist folder.
The version should be 6.00.8397.0. No later version of MSVCRT.DLL should ever be shipped.
Likewise, several OLE files are in the Redist folder.
The PDW almost always works well. When it doesn't the reason is usually
because the installer was made on a late Windows version, such as XP, and attention was not paid
to researching the files being put into the installation, to make sure that they're compatible with
the target systems and that no system files being shipped are newer than the versions on Win2000/ME/XP.
Back to Index
Explanation of the Structure in This Custom Setup1 Code
Start -
Sub Main (Mod1)
Calls
GetPathStrings and
GetProgFolder
to work out folder paths needed by setup.
GetPathStrings gets path of win, sys, temp, etc. and
also path info from
setup.lst.
GetProgFolder gets path of Program Files folder. If it fails then it shows
frmPath
and asks person installing to choose a parent folder for installation. Once there's
a prog. folder path, an app folder is added to that path and entered into text box
of
frmBegin as suggested install path. (ex: "C:\Program files\ABC-Editor" )
Then
Main loads the forms, puts border on forms and shows
fWelcome form.
(Each form load contains the code for its own back gradient coloring.)
fWelcome form (opening splash screen with EULA):
When option button is clicked to agree to license, Continue button is enabled (CmdOK)
Clicking CmdOK calls
ShowBeginInstall (ModFormOps).
ShowBeginInstall hides
fWelcome
and shows
frmBegin.
frmBegin form (shows path of install folder and has Install button):
If Change Location button is clicked,
frmPath is shown to allow for selecting
new program folder.
Optional shortcut checkboxes here can be unchecked to prevent creating those shortcuts.
When Install button is clicked it calls
ProceedInstall (Mod1)
ProceedInstall - main installation routine.
Checks to confirm adequate drive space.
Starts logging of install for uninstall log file.
Calls
CopySection (modInstall)
CopySection
reads
setup.lst [Setup 1 Files] section, getting info. for each file,
extracts each file from CAB and determines whether it should be copied over
or whether an up-to-date copy of the file exists on the computer already.
It copies files with
CopyFile (ModOps) to specified folder and saves reg. info. if relevant.
Most of the actual installing code in
CopySection,
CopyFile, etc.
is original from Microsoft. There are just minimal edits done to accomodate things like not logging App. Data
files.
After files are installed...
ProceedInstall calls
RegisterFiles and
RegisterLicenses.
It then adds the shortcut(s) to the Start Menu, Desktop, Quick Launch with
AddShorcuts (ModShell)
Then it calls
AddPerAppPath (ModRegDeclares) to add a new key to App Paths reg. key.
And it calls
MoveAppRemovalFiles (ModInstall) to
install uninstall log file, clean up install files, and add the uninstall reg. key.
Then,
ExitSetup is called with GintRET_FINISHEDSUCCESS if everything worked out.
Back to Index
Setup1 Without setup.exe - noSE version notes
Setup1 noSE does not need setup.exe, removing approximately 135 KB from setup packages.
It also removes the ugly and pointless gray
window at the beginning of setup that says, "Copying files. Please stand by." The version without setup.exe
is referred to here as the "noSE version" (i.e. "no Setup.Exe") for convenience.
In a normal PDW setup, the setup.exe file has several functions. It extracts 3 files from the CAB:
VB6STKIT.DLL, ST6UNST.EXE, and Setup1.exe.
VB6STKIT.DLL is a specialized DLL that provides
CAB extraction and logging functions for Setup1.exe. The declares for the
VB6STKIT.DLL functions used are in
modDeclares.bas.
ST6UNST.EXE is the VB uninstaller. Normally, setup.exe copies
it to the Windows folder.
Setup.exe also creates a log file and writes some entries into it.
Finally, setup.exe runs
Setup1.exe with a command line that consists of:
[Current path] [Log file path] [ST6UNST.EXE path]
Normally, Setup1.exe starts by processing that command line. The function,
ProcessCommandLine, is removed in the noSE version.
Instead, the noSE version of Setup1 uses
CurDir to find it's location
and calls the new sub
DoBootstrap to take care of the functions
that would have otherwise been performed by setup.exe.
As a result of these code changes setup.exe is no longer needed.
However, there are additional requirements after running the PDW, as explained above.
The final package, when using the noSE version, consists of the CAB file, with setup.lst
and the 3 files listed above stored outside of the CAB. (A good method is to put it all into a
self-executing zip file that runs Setup1.exe when unpacked.)
Technical note: When setup.exe is used, it seems to copy the install CAB file to the Windows folder,
for unknown reasons. It also copies the Setup1 file to the Windows folder. Oddly, with setup.exe removed,
a copy of YourProgram.CAB still ends up in the Windows folder! I have been unable to find any code in Setup1 that
does that. It appears to be a bug in the function
ExtractFileFromCab
from
vb6stkit.dll that actually copies *any* CAB
passed to the function into the Windows folder. Perhaps
ExtractFileFromCab
requires that the CAB be in the same folder? That seems too bizarre to be true, but so far I haven't found any
other possible explanation for how the CAB file gets copied to the Windows folder in the noSE version. In any case,
a function was added to account for the problem: During the function
MoveAppRemovalFiles,
the CAB file in the current directory (the original unpacking, probably the TEMP folder) is deleted as part of
cleanup. An aditional check is then made for a copy of YourProgram.CAB in the Windows folder. If found,
that CAB is also deleted. The final cleanup is more thorough than the normal PDW operation. It leaves behind
only one copy of the Setup1 executable and a copy of setup.lst.
Back to Index
License
You use the accompanying code at your own risk.
There are no claims made for this Setup1 code.
It may be freely distributed as long as no other licensing terms
are applied to it. You may not require others to
add a "vanity note" to their code and this code may not be
distributed as "Open Source" or under any other terms that
add usage and/or redistribution restrictions.
Joe Priestley