PPWIZARD is a free preprocessor for HTML, REXX, Visual Basic or any text files.
[Bottom][Contents][Search][Prev]: Examples[Next]: The Header File - BSD.WIH

Wise Installer OLE Automation

I wanted to be able to create MSI (Windows Installer) packages by defining a simple script and processing this via command line tools that could be run via a make file or simply a batch file.

I found that Wise installer supports OLE automation. I did a bit of research and created a header file which will generate a Visual Basic Script (VbScript) which when executed will create an MSI installer package from scratch (no template required).

The defined macros currently support (basically I believe anything you can do manually you should be able to do via this mechanism):

Other stuff not currently supported can be added via more macros or simply via inline VbScript. Unless you wish to add inline VbScript you do not need to have any knowledge of this language.

There is no need to ever use the wizard although it can be handly to confirm the approach you are using or for debugging your script. Another reason is to examine the tables that wise uses so you know how to update them from the script.

If you have many projects you will find that even though these scripts are simple, 90% of what they do is common between them and a bit of tweeking will quickly get your second, third or hundredth script going in no time. Nothing is hidden by the wizard, code and changes can be commented and PVCS and other standard difference like tools can be used.

I have created a de-compiler (disassembler) for WSI files so that you can take existing packages and create a script from this (it would probably need tweeking to make more readable but should work OK without the tweeking). This decompiler can also be used to work out the differences between two versions of the same package. I have also written a MSI dump program which can tell you a lot about the installer package.

Now the organisation I work for will have tens or hundreds of packages with a lot of common code and settings. For this reason I created the "BSD.WIH" header file (as a front end to the more generic "WISEINST.WIH"

BSDUTIL.WI

This is an extremely simple script which produces an MSI that:

  1. Automates install, user is not prompted.
  2. Adds full support information (web addresses, contact details etc).
  3. Creates a directory and populates in. The source of these files is a directory on the local development machine.
  4. Updates "PATH" environment variable.
  5. Provides full support info/install/repair/change/uninstall support in Add-Remove Programs.
  6. Ensures that in explorer the "tooltip" information for the WSI/MSI package displays relevant information including the package's version number.

Most of the above is performed by my "organsations intermediate header file" which we have set up to ensure all packages we create follow set standards.

    ;----------------------------------------------------------------------------
    ;
    ;    MODULE NAME:   BSDUTIL.WI
    ;
    ;        $Author:   USER "Dennis"  $
    ;      $Revision:   1.0  $
    ;          $Date:   10 May 2001 17:33:28  $
    ;       $Logfile:   C:/DBAREIS/Projects.PVCS/PpwAddOn/WiseInst/bsdutil.wi.pvcs  $
    ;
    ;    DESCRIPTION:   This is my attempt at setting up "BSD_UTIL" correctly.
    ;
    ;                   Wise Installer 3+ & PPWIZARD is required to build the
    ;                   WSI/MSI packages. The WSI dump utility is used to
    ;                   decompile packages.
    ;
    ;                   All known ANX standards are applied "behind the scenes",
    ;                   for example support contact information and the fact
    ;                   that MSI packages install without prompting. Note that
    ;                   as show a lot of information is defaulted and the version
    ;                   number has been autogenerated.
    ;
    ;                   Shortcuts/registry/feature/components etc also supported.
    ;                   Basically if it can be done manually I can do it in a
    ;                   script.
    ;
    ;----------------------------------------------------------------------------
    
    
    ;--- Define Comment for BSDUTIL ---------------------------------------------
    #define    ProductComments                                            \
               This product is a collection of a number of tools required \
               by other products.                                         \
               It also contains BSD standard DLLs such as the LU 6.2      \
               communications API.
    
    
    ;--- Start Package ----------------------------------------------------------
    #define    DEBUG_OUTPUT                ;;Option: Macros display text (no trap handler - VB too stupid)
    #define    ProductName     BSD_UTIL
    #define    BSD_NO_VER_FILE_EXISTS
    #include   "BSD.WIH"
    
    
    ;--- Define all directories used --------------------------------------------
    <$Directory Name="PgmFilesBSD" SubDir="BSD_UTIL">
    
    
    ;--- Want directory to be at end of SYSTEM "PATH" ---------------------------
    <$Path PATH="<$PgmFilesBSD>">
    
    
    ;--- Add files to "COMPLETE" ------------------------------------------------
    <$AddFileWild                                             \
                   SrcDir="P:\DEVELOP\Exported\BSD_UTIL"      \
                  DestDir="<$PgmFilesBSD>"                    \
    ;            includes="cssapi.dll"  ;;default is "*.*"    \
    >
    
    
    
    

LIFE.WI

The example shown above was quite a simple one, this example is a much more complex package.

The "BSD.WIH" header will by default look for a ".VER" file to match the ".WI" package being created, the example above told the header that this was not being supplied.

The ".VER" file contains header information (relevant to all "LIFE" releases) as well as every release distributed with at least a version number and a change history. There are a number of reasons for "splitting" the information, one of the most important is to prevent the actual package script from being modified just because you are creating a new release, we would like it to change only if the installation process does. It also allows someone without any real knowledge of the process to be able to safely update the version information.

The "BSD.WIH" header file reads the version file first extracting any heading information as well as the first (current) change record to pick up the version number that should be used for the current MSI build. It also picks up the change information for this version and adds it to the Generated MSI allowing batch files to scan MSI files for change information independent of any associated readme files etc (which may get lost etc).

The version file for the "LIFE" package looks like:

    ;----------------------------------------------------------------------------
    ;
    ;    MODULE NAME:   LIFE.VER
    ;
    ;        $Author:   USER "Dennis"  $
    ;      $Revision:   1.4  $
    ;          $Date:   28 May 2001 17:24:22  $
    ;       $Logfile:   C:/DBAREIS/Projects.PVCS/PpwAddOn/WiseInst/life.ver.pvcs  $
    ;
    ;    DESCRIPTION:   Holds:
    ;
    ;                      (1) Product description & version history
    ;
    ;                      (2) Version history (current version at top!)
    ;
    ;----------------------------------------------------------------------------
    
    
    ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    ; ProductName = ANX Quote Life
    ; DESCRIPTION = This holds the ANX Quote Life
    ;             = quoting program.
    ;++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
    
    
    ;############################################################################
    MAJ_MIN : 1.03
    VERSION : 01.141
    CHANGES : Contains the 1.0.3 version of the application.
    
    
    ;############################################################################
    MAJ_MIN : 1.02
    VERSION : 01.050
    CHANGES : Contains the 1.0.2 version of the application.
    

The actual package script for "LIFE" looks like:

    ;----------------------------------------------------------------------------
    ;
    ;    MODULE NAME:   LIFE.WI
    ;
    ;        $Author:   USER "Dennis"  $
    ;      $Revision:   1.4  $
    ;          $Date:   24 May 2001 18:17:12  $
    ;       $Logfile:   C:/DBAREIS/Projects.PVCS/PpwAddOn/WiseInst/life.wi.pvcs  $
    ;
    ;    DESCRIPTION:   Creates MSI for ANX Quote Life.
    ;
    ;----------------------------------------------------------------------------
    
    ;--- Where are all the source files located? --------------------------------
    #define  SOURCE_QUOTE_LIFE_PGM  <?=getenv("EXPDIR_ANX_QUOTE_LIFE_PGM",  "Y")>
    #define  SOURCE_QUOTE_LIFE_DATA <?=getenv("EXPDIR_ANX_QUOTE_LIFE_DATA", "Y")>
    #define  ANX_QUOTE_LIFE_ICON    .\ANXQLIFE.ICO
    
    ;--- Some constants ---------------------------------------------------------
    #define  QL_SHORTDIR_TEXT          <$BSD_AIS_STD_PGM_DIRNAME>
    #define  QL_IDRIVE_DATA_DIR_TEXT   I:\Program Files\ANX\<$QL_SHORTDIR_TEXT>
    
    ;--- Load "BSD" support -----------------------------------------------------
    #define  BSD_COMPLETE_FEATURE_DIR  DIR_LIFE_PGM
    #define  BSD_ALLUSERS              0
    #include "BSD.WIH"
    
    
    ;--- Directory - PROGRAM in "\PROGRAM FILES\ANX\ANX Quote Life..." ----------
    <$Directory Name="DIR_LIFE_PGM" Parent="DIR_ProgramFilesBSD"  SubDir="<$QL_SHORTDIR_TEXT>">
    
    ;--- Directory - DATA -------------------------------------------------------
    <$Directory Name="DIR_LIFE_DATA" Parent="DIR_LIFE_PGM"  SubDir="<$BsdIDriveSetupShortDirText>">
    
    ;--- Take care of the data --------------------------------------------------
    #(
       ;--- Create Component ----------------------------------------------------
       <$AddComponent
                 NAME="DIR_LIFE_DATA"
              DestDir="DIR_LIFE_DATA"
    ;;;;   Attributes="<$CATTR_NOT_REMOVE_AT_UNINSTALL>+<$CATTR_NEVER_OVERWRITE>"
       >
    #)
    #(
       <$AddFileWild
           DestDir="<$DIR_LIFE_DATA>"
            SrcDir="<$SOURCE_QUOTE_LIFE_DATA>"
              Add2="DIR_LIFE_DATA" Add2Type="<$IS_COMPONENT>"
           KeyFile="*"
       >
    #)
    
    ;--- EXE Needs to go into it's own component --------------------------------
    <$AddComponent NAME="QLIFE.EXE"  DestDir="DIR_LIFE_PGM">
    #(
       <$AddFileWild
           DestDir="<$DIR_LIFE_PGM>"
            SrcDir="<$SOURCE_QUOTE_LIFE_PGM>"
              Add2="QLIFE.EXE" Add2Type="<$IS_COMPONENT>"
           KeyFile="*"
          includes="ANXQuoteLife.exe"
            EXLIST="QLIFE_PGM"
       >
    #)
    
    
    ;--- These items need to be in seperate components (MS/AIS rules) -----------
    #(
       <$AddFileWild
           DestDir="<$DIR_LIFE_PGM>"
            SrcDir="<$SOURCE_QUOTE_LIFE_PGM>"
              Add2="<$BSD_COMPLETE_FEATURE_NAME>" Add2Type="<$IS_FEATURE>"
          includes="*.dll"
            EXLIST="QLIFE_PGM"
       >
    #)
    #(
       <$AddFileWild
           DestDir="<$DIR_LIFE_PGM>"
            SrcDir="<$SOURCE_QUOTE_LIFE_PGM>"
              Add2="<$BSD_COMPLETE_FEATURE_NAME>" Add2Type="<$IS_FEATURE>"
          includes="*.ocx"
            EXLIST="QLIFE_PGM"
       >
    #)
    
    
    ;--- All other Program files can go into one component ----------------------
    <$AddComponent NAME="DIR_LIFE_PGM" DestDir="DIR_LIFE_PGM">
    #(
       <$AddFileWild
           DestDir="<$DIR_LIFE_PGM>"
            SrcDir="<$SOURCE_QUOTE_LIFE_PGM>"
              Add2="DIR_LIFE_PGM" Add2Type="<$IS_COMPONENT>"
           KeyFile="*"
            EXLIST="QLIFE_PGM"
       >
    #)
    
    
    ;--- Create the shortcut ----------------------------------------------------
    <$AddIcon KEY="ICON_QLIFE.EXE" FILE="<$ANX_QUOTE_LIFE_ICON>">
    #(
       <$AddShortCut
               RowKey="SC_ANX_QUOTE_LIFE_PGM"
                Title="ANX Quote Life <$MajVersion>"
                ScDir="SCDIR_BUSAPPS"
             ScTarget="anzquotelife.exe"
            ScWorkDir="DIR_LIFE_PGM"
               ScDesc="Life Insurance Quoting Application (BSD v<$BsdVersion>)"
                 Add2="QLIFE.EXE"
             Add2Type="<$IS_COMPONENT>"
           ScIconNumb=0
            ScIconKey="ICON_QLIFE.EXE"
       >
    #)
    
    
    ;--- Fix 2 Wise Installer BUGs ----------------------------------------------
    <$HereWeAre "Working around 2 Wise Installer bugs (Icon Indexes 'adjusted' + Working directory bug)">
    <$TABLE "Shortcut">
       <$Row "SC_ANX_QUOTE_LIFE_PGM" WkDir="DIR_LIFE_PGM" IconIndex="0">
    <$/TABLE>
    
    
    ;--- Add INI ----------------------------------------------------------------
    <$IniFile FILE="ANXQUOTE.INI" SECTION="FileDetails" DIR="DIR_LIFE_PGM" ADD2="DIR_LIFE_PGM">
       <$IniAdd Key="AgentDetailsFilePath"      Value="<$QL_IDRIVE_DATA_DIR_TEXT>">
       <$IniAdd Key="CustomerFilePath"          Value="<$QL_IDRIVE_DATA_DIR_TEXT>">
       <$IniAdd Key="QuoteFilePath"             Value="<$QL_IDRIVE_DATA_DIR_TEXT>">
       <$IniAdd Key="TempFilePath"              Value="<$QL_IDRIVE_DATA_DIR_TEXT>">
       <$IniAdd Key="CustomerQuoteKillDuration" Value="60">
       <$IniAdd Key="CustomerQuoteKillDate"     Value="30/12/2001">
       <$IniAdd Key="Bank"                      Value="Y">
    <$/IniFile>
    
    
    
    ;--- Add registry entries ---------------------------------------------------
    #define+ HKEY_DEFAULT      <$CLASSES_ROOT>
    #define+ DEFAULT_ADD2      REG_CLASSES_ROOT
    #define+ DEFAULT_ADD2TYPE  <$IS_COMPONENT>
    <$AddComponent NAME="<$DEFAULT_ADD2>" DestDir="DIR_LIFE_PGM">
    #(
       <$AddRegValue
           KeyPath="Y" RowKey="KeyPathRegEntry"
               Key="CalculationXDll.clsCalculation"
             Value="CalculationXDll.clsCalculation"
       >
    #)
    #(
        <$AddRegValue
               Key="MedFinReqXDll.clsMedicalFinancialReq\Clsid"
             Value="{03AC0317-0756-11D3-9CDA-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="QuoteXDll.clsQuotes"
             Value="QuoteXDll.clsQuotes"
        >
    #)
    #(
        <$AddRegValue
               Key="CalculationXDll.clsCalculation\Clsid"
             Value="{C47325AD-0CF3-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="DiscountBandXDll.clsDiscountBands"
             Value="DiscountBandXDll.clsDiscountBands"
        >
    #)
    #(
        <$AddRegValue
               Key="MedFinReqXDll.clsMedicalFinancialReqs\Clsid"
             Value="{03AC0319-0756-11D3-9CDA-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="ConstantXDll.clsConstant"
             Value="ConstantXDll.clsConstant"
        >
    #)
    #(
        <$AddRegValue
               Key="CalculationXDll.clsCalculationResults\Clsid"
             Value="{C47325AB-0CF3-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="DiscountBandXDll.clsDiscountBand\Clsid"
             Value="{EBB4C949-0755-11D3-9CDA-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="CalculationXDll.clsCalculationResults"
             Value="CalculationXDll.clsCalculationResults"
        >
    #)
    #(
        <$AddRegValue
               Key="CustomerXDll.clsCustomer\Clsid"
             Value="{C06B9199-0CCF-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="ProductXDll.clsProduct\Clsid"
             Value="{A76A95A1-0CF3-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="CalculationXDll.clsCalculationResult"
             Value="CalculationXDll.clsCalculationResult"
        >
    #)
    #(
        <$AddRegValue
               Key="DiscountBandXDll.clsDiscountBands\Clsid"
             Value="{EBB4C947-0755-11D3-9CDA-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="MedFinReqXDll.clsMedicalFinancialReqs"
             Value="MedFinReqXDll.clsMedicalFinancialReqs"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.TDBDropDown"
             Value="True DBDropDown Control"
        >
    #)
    #(
        <$AddRegValue
               Key="DiscountBandXDll.clsDiscountBand"
             Value="DiscountBandXDll.clsDiscountBand"
        >
    #)
    #(
        <$AddRegValue
               Key="ProductXDll.clsProducts"
             Value="ProductXDll.clsProducts"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.TDBGrid"
             Value="True DBGrid  Control"
        >
    #)
    #(
        <$AddRegValue
               Key="CustomerXDll.clsCustomers\Clsid"
             Value="{C06B9197-0CCF-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.Style"
             Value="APEX True DBGrid Style Object"
        >
    #)
    #(
        <$AddRegValue
               Key="CalculationXDll.clsCalculationResult\Clsid"
             Value="{C47325A9-0CF3-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="PrintQuoteXDll.clsPrint\Clsid"
             Value="{BDFAFAE8-0E58-11D3-9CAB-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="ProductXDll.clsProduct"
             Value="ProductXDll.clsProduct"
        >
    #)
    #(
        <$AddRegValue
               Key="ProductXDll.clsProducts\Clsid"
             Value="{A76A95A3-0CF3-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="CalculationXDll.clsCalculations"
             Value="CalculationXDll.clsCalculations"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.ValueItem\CLSID"
             Value="{00028C65-0000-0000-0000-000000000046}"
        >
    #)
    #(
        <$AddRegValue
               Key="PrintQuoteXDll.clsPrint"
             Value="PrintQuoteXDll.clsPrint"
        >
    #)
    #(
        <$AddRegValue
               Key="QuoteXDll.clsQuotes\Clsid"
             Value="{8B14AE1E-0CCF-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="CalculationXDll.clsCalculations\Clsid"
             Value="{C47325AF-0CF3-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="CustomerXDll.clsCustomers"
             Value="CustomerXDll.clsCustomers"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.Style\CLSID"
             Value="{00028C6C-0000-0000-0000-000000000046}"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.TDBDropDown\CLSID"
             Value="{00028C70-0000-0000-0000-000000000046}"
        >
    #)
    #(
        <$AddRegValue
               Key="MedFinReqXDll.clsMedicalFinancialReq"
             Value="MedFinReqXDll.clsMedicalFinancialReq"
        >
    #)
    #(
        <$AddRegValue
               Key="QuoteXDll.clsQuote"
             Value="QuoteXDll.clsQuote"
        >
    #)
    #(
        <$AddRegValue
               Key="QuoteXDll.clsQuote\Clsid"
             Value="{8B14AE1C-0CCF-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="CustomerXDll.clsCustomer"
             Value="CustomerXDll.clsCustomer"
        >
    #)
    #(
        <$AddRegValue
               Key="ConstantXDll.clsConstant\Clsid"
             Value="{3DCFDC55-0CF3-11D3-9CA9-00C04F886CB8}"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.TDBGrid\CLSID"
             Value="{00028C49-0000-0000-0000-000000000046}"
        >
    #)
    #(
        <$AddRegValue
               Key="TrueDBGrid50.ValueItem"
             Value="APEX True DBGrid Value Item Object"
        >
    #)
    
    
    ;--- Set up I: drive (VBS, INF(s) and registry) -----------------------------
    #define   IDRV_DIRKEY_VBS       DIR_LIFE_DATA              ;;Key into directory table (with only one dir INF/VBS in same dir as data)
    #define   IDRV_DIRINFO_INF.1    ~<$ProductName>.INF        ;;Name of INF file (typically shortname, but actually relative to VBS dir)
    #define   IDRV_DIRINFO_DIRKEY.1 DIR_LIFE_DATA              ;;Key to directory table
    #define   IDRV_DIRINFO_SRC.1    <$SOURCE_QUOTE_LIFE_DATA>\*.*(CPYFLG_NeverOverwrite)
    #define   IDRV_DIRINFO_ON_I.1   <$QL_IDRIVE_DATA_DIR_TEXT> ;;Full dir name on I drive
    #include "IDRIVESU.WIH"
    


[Top][Contents][Search][Prev]: Examples[Next]: The Header File - BSD.WIH

PPWIZARD Manual
My whole website and this manual itself was developed using PPWIZARD (free preprocessor written by Dennis Bareis)
Friday June 01 2001 at 5:58pm