David,
Here is another way.
I wrote a DLL for my Outlook Add-In installer package (MSI file
created using Visual Studio Installer) that, among other things, makes
decisions based on the Outlook version. I detect the Outlook version
by reading the Registry entry:
HKEY_CLASSES_ROOT\Outlook.Application\CurVer
It will contain:
Outlook.Application.8 = Outlook 97
Outlook.Application.9 = Outlook 2000
Outlook.Application.10 = Outlook 2002
Outlook.Application.11 = Outlook 2003
My DLL does a few special things during the install, and then returns
0 (success) or 1 (failure) to the Microsoft installer. If 0 is
returned, the installer continues. If 1 is returned, the installer
aborts with an generic termination error message (my DLL has already
informed the user of the specific problem using MessageBoxes). The
point is that the DLL can easily abort the install in an orderly
fashion.
Writing the DLL with pass=0/fail=1 return is straightforward. The
trickier part is plugging the DLL into your MSI package and calling
it. I have done this both manually using Orca, and script driven
using SQL-ish code and the MSI API in a purpose built utility.
In either case, you add to the tables in the MSI file (note that 105
below may not be the correct Sequence in your implementation):
Binary
Name InstValDLL
Data [Binary Data] <-- binary for DLL above
CustomAction
Action CA_ValOutlookVersion
Type 1
Source InstValDLL
Target InstValOutlookVersion
InstallUISequence
Action CA_ValOutlookVersion
Condition NOT Installed
Sequence 105
The 'NOT Installed' condition is needed to prevent the function from
also being called during MSI file uninstall.
The 'Sequence' number is used to place execution of the DLL target
function before or after other existing steps in the MSI installation.
The value 105 above results in InstValOutlookVersion being called:
:
LaunchConditions 100
CA_ValOutlookVersion 105
AppSearch 400
:
It's a little complicated to get this all working initially, but it
works, and in the end you have the freedom to write custom installer
code in C in your DLL.
Once you have this working, it is easy to add other DLLs that are
called at different installer Sequence numbers, or other entry point
functions in the same DLL that are called at different Sequence
numbers, in different tables such as InstallUISequence,
InstallExecuteSequence, etc. I have done both. Works great.
If you decide to take this approach, pay particular attention to the
Type field in the CustomAction. I learned the hard way that I need a
value of 1025 so my DLL function will run at the requested Sequence
point at installer *run time*, as opposed to during installer *script
generation* time.
The value 1025 is 1 (DLL binary) with a 1024 flag bias, per
microsoft.com and newsgroup postings, to make it a 'deferred'
CustomAction:
0x00000000 0 Immediate execution.
0x00000400 1024 Queues for execution at scheduled point
within script. This flag designates that
this is a deferred execution custom action.
If the 1024 flag bias is not included above, the CustomAction is
immediate, which means it runs during install script generation. If
the 1024 flag bias is included, the CustomAction is deferred, which
means it runs as the script executes, which is what is wanted.
Jim