PPWIZARD is a free preprocessor for HTML, REXX, Visual Basic or any text files.
[Bottom][Contents][Search][Prev]: The Header File - BSD.WIH[Next]: Creating HTML pages from Windows URL Shortcuts or OS/2 URL Objects

The Header File - WISEINST.WIH

This is the header file that is provides generic support for the creation of Wise Installer ".WSI" packages as well as Microsoft's Windows Installer ".MSI" packages.

This is an extremely powerful tool which eliminates the need for using the Wise Installer wizard when creating installation packages, for more information and examples on how some packages might look have a look at "Wise Installer OLE Automation".

This facility allows you to automate package generation as well as allowing people without full Wise/packaging training to support and create packages. Package creation is consistant as nothing is ever forgotten.

The header file is not documented so for that reason only a person writing a script would need to refer to the file. If interest in this facility is shown I may add documentation.

The header follows:

    ;----------------------------------------------------------------------------
    ;
    ;    MODULE NAME:   WISEINST.WIH
    ;
    ;        $Author:   USER "Dennis"  $
    ;      $Revision:   1.41  $
    ;          $Date:   28 Nov 2001 16:59:10  $
    ;       $Logfile:   C:/DBAREIS/Projects.PVCS/PpwAddOn/WiseInst/wiseinst.wih.pvcs  $
    ;
    ;    DESCRIPTION:   Provides a script like OLE AUTOMATION SUPPORT for
    ;                   wise installer.
    ;
    ;                   Do NOT touch this file it is included by your script!
    ;
    ;                   No VB knowledge is required.
    ;
    ;                   To build (uses PPWIZARD - free preprocessor):
    ;
    ;                      REM *** Convert script into VB code ******************
    ;                      ppwizard WISETEST.wi /output:out\*.vbs /other /dependson:out\*.dep /define:GENERATE=c:\tmp\WISETEST /errorfile:out\ppwizard.err
    ;
    ;                      REM *** Execute VB code to create MSI package ********
    ;                      if not errorlevel 1 cscript out\WISETEST.vbs
    ;
    ;                   PPWIZARD is the most powerful preprocessor available
    ;                   AND IT'S FREE (personal or commercial use),
    ;                   it's homepage is at:
    ;
    ;                       http://www.labyrinth.net.au/~dbareis/ppwizard.htm
    ;
    ;                   Note that if you wish to keep Windows Installer GUIDS
    ;                   fixed then you can use the ppwizard add-on "NEEDGUID"
    ;                   to "remember" them for you.
    ;
    ;           HELP:   The Wise Wizard, particularly the TABLE view under
    ;                   the "SETUP EDITOR" can be very handy for checking that
    ;                   you have correctly done something or simply to work
    ;                   out what to do.
    ;
    ;                   What you can also do if use my "DUMPWSI" tool after
    ;                   manually making a change to work out what has changed
    ;                   and either user the dumped output as is or simply for
    ;                   diagnostic purposes.
    ;
    ;        WARNING:   It is early days for this script (and my knowledge)
    ;                   so things will probably change for future versions
    ;                   of this header. Always back up any existing scripts
    ;                   as well as older versions of ppwizard and this header
    ;                   before upgrading.
    ;----------------------------------------------------------------------------
    
    
    ;--- Define Version number of this install support --------------------------
    #ifdef   WISEINST_VERSION
             #eof 1;                ;;Don't process again if included twice!
    #endif
    #define  WISEINST_VERSION   01.332
    #require 01.086
    #option  PUSH DefineMacroReplace=ON
    #define  WISEINST_HEADER    <?InputComponent>
    #option  POP
    
    ;--- Make sure user specified the name of the output file -------------------
    #ifndef GENERATE
            #error ^The define "GENERATE" must contain name of output WISE package^
    #endif
    #define  GENERATE_WSI   <$GENERATE>.wsi
    #define  GENERATE_MSI   <$GENERATE>.msi
    #define? GENERATE_RPT   <$GENERATE>.htm
    
    ;--- A prefix for Special "generator" type properties -----------------------
    #define? WISEINST_PROP_PREFIX     ____
    
    ;--- Default feature --------------------------------------------------------
    #define Complete           Complete            ;;Default Feature Name
    
    ;--- Add to Component or Feature --------------------------------------------
    #define IS_FEATURE             0
    #define IS_COMPONENT           1
    
    ;--- Make it easier to specify multiple items all added to same components etc ---
    #define? DEFAULT_FEATURE       <$Complete>
    #define? DEFAULT_ADD2          <$DEFAULT_FEATURE>
    #define? DEFAULT_ADD2TYPE      <$IS_FEATURE>
    
    ;--- How to add wildcard files from directory -------------------------------
    #define NO_SUBDIRECTORIES          0
    #define SUBDIRECTORIES             1
    #define UPDATE_NEW_COMPONENTS      2
    
    
    ;--- Define some directory location -----------------------------------------
    #define DESKTOP_DIR        Windows\Profiles\Desktop
    #define STARTBAR_DIR       Windows\Profiles\Start Menu
    #define STARTBAR_PGM_DIR   <$STARTBAR_DIR>\Programs
    
    ;--- Set default for trap detection handler ---------------------------------
    #ifdef DEBUG_OUTPUT
           ;--- No runtime trap handler if debugging (VB is too stupid!) --------
           #define? RUNTIME_TRAPS_DETECTED N
           #define? VERBOSE_OUTPUT         Y
    #elseif
           ;--- In "Production" mode probably want trap detection ---------------
           #define? RUNTIME_TRAPS_DETECTED Y
           #define? VERBOSE_OUTPUT         N
    #endif
    
    ;--- Start/end of Install script --------------------------------------------
    #define Package   <$VBSCRIPT_AT_START>
    #define /Package                                          \
            <$SRCLINE 'Processing "/Package" macro'>         -\
            <$AddScheduleCustomAction>                       -\
            #ifndef WISEINST_DONT_CREATE_HTML_AUTOMATICALLY  -\
               <$GenerateAnyHtmlReports>                     -\
            #endif                                           -\
            <$VBSCRIPT_AT_END>
    
    ;--- Define 'X' codes that can be used within VB "literal" strings ----------
    #DefineRexx ''
       do  Ascii = 0 to 255
           ;--- This code is only to be used within a VB STRING (double quoted) ---
           VbCode = '" & chr(' || Ascii || ') & "'
    
           ;--- Set up the code -------------------------------------------------
           call SetXCode d2x(Ascii), VbCode
       end;
       call SetXCode "CRLF", '" & vbCRLF & "'
       call SetXCode "CR",   '" & vbCR & "'
       call SetXCode "LF",   '" & vbLF & "'
       call SetXCode "DQ",   '" & chr(' || c2d('"') || ') & "'
    #DefineRexx
    #DefineRexx REXX_$$VBSTR
                ;--- Handle user entering double quotes in a value --------------
                TheValue = '"' || ReplaceString(TheValue, '"', '<?xDQ>') || '"';
    #DefineRexx
    
    ;--- Allows imbedding of VB statements/variables in "literals" --------------
    #RexxVar ^VbDq^ =x= ^"^     ;;Can't use double quotes directly
    #define  VBIMBED                                                       \
             <?xVbDq>      ;;End literal with double quote                 \
             &             ;;Concatenate user's VB statement/variable      \
             {$STAT}       ;;User's VB statement/variable                  \
             &             ;;Concatenate rest of literal                   \
             <?xVbDq>      ;;Start Literal
    
    ;--- Used to remember location in code (make up for stupid VB deficiency) ---
    #NextId
    #RexxVar    @@PrevSrcLineMarker = ''
    #DefineRexx Rexx2GetSrcLineInfo
                ;--- Create a SHORT file location string ------------------------
                @@F  = InputComponentLevel();
                @@Fl = InputComponentLineLevel();
                @@Fs = _Filespec('name', @@F);
                @@LocStr = @@Fs || '(' || @@Fl || ')';
    
                ;--- Work out what we wish to show as the "source line" ---------
                if  AltText4SrcLine <> '' then
                    @@SrcLine = AltText4SrcLine;    ;;We have overridden the normal value
                else
                    @@SrcLine = space(GetFileLineBeingProcessed())
    
                ;--- Already output info once? ----------------------------------
                @@Vb = ''
                @@SrcLineMarker = @@LocStr || ':' || @@SrcLine;
                if @@SrcLineMarker <> @@PrevSrcLineMarker then
                do
                   ;--- Generate VB Comments ------------------------------------
                   @@VB = @@VB || '<?NewLine><?NewLine><?NewLine>'
                   @@VB = @@VB || "'" || copies('=', 70) || '<?NewLine>'
                   @@VB = @@VB || "'Line " || @@Fl || ' of ' || @@F || '<?NewLine>'
                   @@VB = @@VB || "'" || @@SrcLine || '<?NewLine>'
                   @@VB = @@VB || "'" || copies('=', 70) || '<?NewLine>'
                   @@VB = @@VB || '<?NewLine>'
                   @@PrevSrcLineMarker = @@SrcLineMarker;
                end;
    
               ;--- VB code to Record/display location --------------------------
               @@UserCmt = ReplaceString(@@UserCmt, '"' || '""');
               @@VB = @@VB || '<?NewLine>'
               @@VB = @@VB || 'HereWeAre "' || @@LocStr || '", "' || @@UserCmt || '"'
    #DefineRexx
    #( ''
       #define HereWeAre
               ;--- Get info about where we are and what we are doing -----------
               #RexxVar @@UserCmt = ~{$#1=^^}~
               #evaluate ^^ ^<$Rexx2GetSrcLineInfo>^
    
               ;--- The above generated any required VB (into a rexx variable) --
               <??@@Vb>
    #)
    #define HEREWEARE_LOCN  ;;Useful if VB needs to be called directly \
            <?InputComponent $$SHORT>(<?InputComponentLine>)
    #DefineRexx REXX_$$SHORT
                ;--- Transformation to return short name given one with path ----
                TheValue = _filespec('name', TheValue);
    #DefineRexx
    #define SRCLINE                                    \
            #RexxVar AltText4SrcLine = '{$#1 $$SQx2}'
    <$SRCLINE ''>
    
    
    ;--- Useful Macros (use if you write imbedded VbSCript!) --------------------
    #define WiseObj         WiseObj                ;;In case interface completely changes...
    #define DieIfKeyInvalid KeyMustBeOk({$KEYVAR="Key"})
    #define DieIfNotOk      BoolMustBeTrue(Ok)
    
    
    ;--- Work out the name of this header file ----------------------------------
    #DefineRexx ''
       WiseInstHeaderFile = '<?InputComponent>';
    #DefineRexx
    
    
    ;--- Wise Hide compile dialog box -------------------------------------------
    #define HideCompileDialogBox        \
            <$HereWeAre "{$MacName}">  %\
            <$WiseObj>.SetSilent
    
    ;--- Set properties ---------------------------------------------------------
    #(   '<?NewLine>'
       #define SetProperty
               <$HereWeAre "{$?MacName} - {$Name}">
               #RexxVar RxPropertyValue = ^{$Value}^
               Ok = <$WiseObj>.SetProperty("{$Name}", <??RxPropertyValue $$VBSTR>)
               <$DieIfNotOk>{$!}
    #)
    ;**      CommentBlock  /* (Thursday 24/05/2001, 09:20:02, by Dennis Bareis) */
    ;**+--------------------------------------------------------------------------
    ;**|#(   '<?NewLine>'
    ;**|   #define SetProperty
    ;**|           <$HereWeAre "{$?MacName} - {$Name}">
    ;**|           Ok = <$WiseObj>.SetProperty("{$Name}", {$Value $$VBSTR})
    ;**|           <$DieIfNotOk>{$!}
    ;**|#)
    ;**+--------------------------------------------------------------------------
    ;**                    /* (Thursday 24/05/2001, 09:20:02, by Dennis Bareis) */
    
    ;--- Set Load Template ------------------------------------------------------
    #(   '<?NewLine>'
       #define LoadTemplate
               <$HereWeAre "{$?MacName} - {$File}">
               Ok = <$WiseObj>.Open("{$File}")
               <$DieIfNotOk>{$!}
    #)
    
    ;--- Add Feature ------------------------------------------------------------
    #define  FDISP_INVISIBLE                                 0
    #define  FDISP_VISIBLE_AND_EXPANDED                      1
    #define  FDISP_VISIBLE_AND_COLLAPSED                     2
    #define? FDISP_DEFAULT                                   <$FDISP_VISIBLE_AND_COLLAPSED>
    #define  FILVL_NEVER_INSTALL                             0
    #define  FILVL_ALWAYS_INSTALL                            1
    #define  FILVL_NORMAL                                    3
    #define? FILVL_DEFAULT                                   <$FILVL_NORMAL>
    #define  FATTR_ADVERTISING_NONE                          0
    #define  FATTR_FAVOR_SOURCE_INSTALL                      1
    #define  FATTR_FAVOR_PARENT_ATTRIBUTES                   2
    #define  FATTR_FAVOR_ADVERTISED_FEATURE                  4
    #define  FATTR_DISALLOW_ADVERTISING                      8
    #define  FATTR_DISALLOW_OPT_TO_SET_ABSENT               16
    #define  FATTR_DISALLOW_ADVERTISED_IF_OPSYS_WONT_ALLOW  32
    #define  FATTR_REQUIRED_FEATURE                         <$FATTR_DISALLOW_OPT_TO_SET_ABSENT>
    #define? FATTR_DEFAULT                                  <$FATTR_FAVOR_ADVERTISED_FEATURE>+<$FATTR_REQUIRED_FEATURE>
    #define AddFeature                                                \
            <$HereWeAre "{$?MacName} - '{$Name}' to '{$Parent=^^}'"> %\
            #evaluate+ ^BitsCombined^ ^<$FATTR_DEFAULT>^             -\
            Ok = <$WiseObj>.AddFeature(                               \
                  "{$Name}",                                          \
                  "{$Parent=^^}",                                     \
                  "{$Title}",                                         \
                  "{$Description=^LINE_<?InputComponentLine>^}",      \
                  {$Display=^<$FDISP_DEFAULT>^},                      \
                  {$Level=^<$FILVL_DEFAULT>^},                        \
                  "{$DestDir}",                                       \
                  {$Attributes="<$BitsCombined>"}                     \
            )                                                        %\
            <$DieIfNotOk>{$!}
    
    ;--- Add Component ----------------------------------------------------------
    #define  CATTR_CANT_RUN_FROM_SOURCE       0
    #define  CATTR_ONLY_RUN_FROM_SOURCE       1
    #define  CATTR_RUN_FROM_SOURCE_OR_LOCAL   2
    #define  CATTR_KEY_PATH_FOR_REGISTRY      4
    #define  CATTR_INC_SHARED_DLL_COUNT       8
    #define  CATTR_NOT_REMOVE_AT_UNINSTALL    16
    #define  CATTR_KEY_PATH_FOR_ODBC          32
    #define  CATTR_COMPONENT_IS_TRANSITIVE    64
    #define  CATTR_NEVER_OVERWRITE            128
    #define? CATTR_DEFAULT                    <$CATTR_CANT_RUN_FROM_SOURCE>
    #define AddComponent                                             \
            <$HereWeAre "{$?MacName} - '{$Name}' to '{$Feature="<$DEFAULT_FEATURE>"}'"> %\
            #evaluate+ ^BitsCombined^ ^<$CATTR_DEFAULT>^            -\
            Ok = <$WiseObj>.AddComponent(                            \
                  "{$Name}",                                         \
                  "{$DestDir}",                                      \
                  "{$CONDITION=^^}",                                 \
                  {$Attributes="<$BitsCombined>"}                    \
            )                                                       %\
            <$DieIfNotOk>                                           %\
            Ok = <$WiseObj>.AddComponentToFeature(                   \
                  "{$Name}",                                         \
                  "{$FEATURE}"                                       \
            )                                                       %\
            <$DieIfNotOk>{$!}
    
    
    ;----------------------------------------------------------------------------
    ;--- Component GUID (to "fix" GUIDs have a look at "NEEDGUID.H") ------------
    ;----------------------------------------------------------------------------
    #( '<?NewLine>'
       #define SetComponentGuid
               <$HereWeAre "{$?MacName} - {$COMPONENT}">
               Ok = <$WiseObj>.SetComponentGUID("{$COMPONENT}", "{$GUID}")
               <$DieIfNotOk>{$!}
    #)
    
    ;----------------------------------------------------------------------------
    ;--- ADD MERGE MODULE -------------------------------------------------------
    ;----------------------------------------------------------------------------
    #( '<?NewLine>'
       #define AddMergeModule
               <$HereWeAre "{$?MacName} - {$MODULE}">
               #evaluate ^^ ^<$GetFullNameMergeModule FILENAME="{$MODULE}" FULLVAR="FULLMERGENAME">^
               Ok = <$WiseObj>.AddMergeModule("<??FULLMERGENAME>", "{$ADD2}", "{$DIRECTORY}")
               <$DieIfNotOk>{$!}
    #)
    #DefineRexx 'GetFullNameMergeModule'          ;;Handy from an otherwise non-rexx macro
       call Debug 'Macro: GetFullNameMergeModule for "{$FileName}"'
       call DebugIndent 1;
       if  left('{$FileName}', 1) = '[' then
       do
           call Debug 'File refers to "[WisePath]" or similar (can''t validate).'
           {$FullVar} = '{$FileName}';
       end;
       else
       do
           ;--- Want to validate filename ---------------------------------------
           {$FullVar} = FindFile('{$FileName}');
           if  {$FullVar} = '' then
           do
               ;--- Could not find look in Wise Modules -------------------------
               @@WP = 'C:\Program Files\Wise for Windows Installer\modules';
               call Debug 'Having a look in "' || @@WP || '"'
               {$FullVar} = stream(@@WP || '\{$FileName}', 'c', 'query exists');
               if  {$FullVar} = '' then
                   error('The merge module "{$FileName}" could not be found!')
           end;
           call Debug 'Full name: ' || {$FullVar}
           call Debug 'Dated    : ' || stream({$FullVar}, 'c', 'query datetime')
           call Debug 'Size     : ' || stream({$FullVar}, 'c', 'query size')
       end;
       call DebugIndent -1;
    #DefineRexx
    
    
    ;----------------------------------------------------------------------------
    ;--- SELF REGISTRATION (OCX and DLL COM objects etc) ------------------------
    ;----------------------------------------------------------------------------
    #NextId
    #( '<?NewLine>'
       #define SelfRegister
       <$HereWeAre "{$?MacName} - {$#1} = {$SELFREG=^Y^}">
       #if ['{$SELFREG}' = 'N']
           #define+ @@SelfReg  false  ;;Want to remove self registration info
       #elseif
           #define+ @@SelfReg  true   ;;Want this filekey self registered
       #endif
       OK = <$WiseObj>.SetFileSelfRegister("{$#1}", <$@@SelfReg>)
       BoolMustBeTrue(Ok)
    #)
    
    
    
    ;----------------------------------------------------------------------------
    ;--- Handle Exclude lists ---------------------------------------------------
    ;----------------------------------------------------------------------------
    #define ExcludeListClear           \
            #evaluate ^^ ^<$Rexx4ExcludeListClear {$?}>^
    #define ExcludeListAddWild         \
            #evaluate ^^ ^<$Rexx4ExcludeListAddWild {$?}>^
    #NextId
    #DefineRexx 'Rexx4ExcludeListClear'
       ;--- Work out where to store info ----------------------------------------
       <$Rexx4WorkOutStem EXLIST=^{$EXLIST}^ VAR="@@Stem">
    
       ;--- Now clear the "array" -----------------------------------------------
       call value @@Stem || '.0', 0;       ;;Zero entries in the array
    #DefineRexx
    #DefineRexx 'Rexx4WorkOutStem'
       ;--- Try and use username as is ------------------------------------------
       @@Base = '{$EXLIST}'
       if  symbol(@@Base) = 'BAD' then
           @@Base = c2x(translate(@@Base));
    
       ;--- Return the stem without dot we will use -----------------------------
       {$VAR} = 'EXLIST_' || @@Base;
    
       ;--- Make sure the variable exists ---------------------------------------
       if  symbol({$VAR} || '.0') <> 'VAR' then
       do
           ;--- Init to empty array ---------------------------------------------
           call value {$VAR} || '.0', 0;
       end;
    #DefineRexx
    #DefineRexx 'Rexx4ExcludeListAdd1'
       ;--- Work out where to store info ----------------------------------------
       <$Rexx4WorkOutStem EXLIST=^{$EXLIST}^ VAR="@@Stem">
    
       ;--- Make upper case for faster compares later ---------------------------
       @@FileU = translate({$FILEVAR});
    
       ;--- Now add into the array ----------------------------------------------
       @@Count = value(@@Stem || '.0') + 1;           ;;Get count + Increment it
       call value @@Stem || '.' || @@Count, @@FileU;  ;;Save file
       call value @@Stem || '.0',           @@Count;  ;;Save updated count
    #DefineRexx
    #DefineRexx 'Rexx4ExcludeListAddStem'
       ;--- Work out where to store info ----------------------------------------
       <$Rexx4WorkOutStem EXLIST=^{$EXLIST}^ VAR="@@Stem">
    
       ;--- Add to the exclude list ---------------------------------------------
       @@Count = value(@@Stem || '.0');                     ;;Get current count
       do  @@I = 1 to {$FILESTEM}.0
           ;--- Add each file to the exclude list -------------------------------
           @@Count = @@Count + 1;
           call value @@Stem || '.' || @@Count, translate({$FILESTEM}.@@I);
       end
       call value @@Stem || '.0', @@Count;                  ;;Save updated count
    #DefineRexx
    #DefineRexx 'Rexx4ExcludeListFileIn'
       ;--- Work out where info stored ------------------------------------------
       <$Rexx4WorkOutStem EXLIST=^{$EXLIST}^ VAR="@@Stem">
    
       ;--- Convert passed file to uppercase ------------------------------------
       @@Look4 = translate({$FILEVAR});
    
       ;--- Add to the exclude list ---------------------------------------------
       {$FOUNDVAR} = 'N';
       do  @@I = 1 to value(@@Stem || '.0')
           ;--- Check passed filename against exclude list entry ----------------
           if  @@Look4 = value(@@Stem || '.' || @@I) then
           do
               ;--- Found entry -------------------------------------------------
               {$FOUNDVAR} = 'Y';
               leave;                ;;Exit loop
           end;
       end
    #DefineRexx
    #DefineRexx 'Rexx4ExcludeListAddWild'
       ;--- Get list of files to be excluded ------------------------------------
       @@Files.0 = 0;
       Look4     = "{$FILES}";
       call _SysFileTree   Look4, "@@Files";
       if  @@Files.0 = 0 then
       do
           ;--- Did not find any files, is this OK? -----------------------------
           if  '{$NONEOK=^N^}' = 'N' then
               Error('No files matched "' || Look4 || '"!');
       end
    
       ;--- Add to the stem -----------------------------------------------------
       <$Rexx4ExcludeListAddStem EXLIST=^{$EXLIST}^ FILESTEM="@@Files">
    #DefineRexx
    
    
    ;--- Add file ---------------------------------------------------------------
    #define  SFATTR_READ_ONLY                1
    #define  SFATTR_HIDDEN                   2
    #define  SFATTR_SYSTEM                   4
    #define  SFATTR_VITAL                    512             ;;Installation fails if file can't be installed
    #define  SFATTR_CONTAINS_CHECKSUM        1024
    #define  SFATTR_UNCOMPRESSED_OUTSIDE     8192
    #define? SFATTR_DEFAULT                  <$SFATTR_VITAL>
    #NextId
    #define AddFile1                                                            \
            ;--- Define any required directories -------------------------     -\
            #evaluate ^^ ^@@DIR  = _filespec('L', '{$DESTINATION}')^           -\
            #evaluate ^^ ^@@NAME = _filespec('N', '{$DESTINATION}')^           -\
            #evaluate ^^ ^<$Rexx4MakeDirTree DIRECTORY="<??@@DIR>">^           -\
            <??Wi>                                                             -\
            #option  PUSH DefineMacroReplace=ON                                -\
            #define+ @@DEST <??WiDirRef>\<??@@Name>   ;;Rebuild destination    -\
            #option  POP                                                       -\
                                                                               -\
            ;--- Create VbScript to add file -----------------------------     -\
            <$HereWeAre "{$?MacName} - {$SOURCE}">                             %\
            #DependsOn INPUT "{$SOURCE}"                                       -\
            KeyPath = <$WiseObj>.AddFileEx(                                     \
                      "{$SOURCE}",                                              \
                      "<$@@DEST>",                                              \
                      {$Attributes="<$SFATTR_DEFAULT>"},                        \
                      "{$Add2="<$DEFAULT_ADD2>"}", ;;Feature/Component name     \
                      {$Add2Type="<$DEFAULT_ADD2TYPE>"},                        \
                      PvComponent                                               \
            )                                                                  %\
            <$DieIfKeyInvalid KEYVAR="KeyPath">{$!}                            %\
                                                                               -\
            ;--- If requested make this a Keyfile ------------------------     -\
            #if  ['{$KEYPATH=^N^}' = 'Y']                                      -\
               <$HereWeAre "{$?MacName} - SetComponentKeyPath()" VBCMT="N">    %\
               Ok = <$WiseObj>.SetComponentKeyPath("{$Add2}", KeyPath)         %\
               <$DieIfNotOk>                                                   %\
            #endif                                                             -\
                                                                               -\
            ;--- Self Register this file? --------------------------------     -\
            #if  '{$SelfReg=""}' <> ''                                         -\
               <$SelfRegister #1=`<$VbImbed STAT=^KeyPath^>` SelfReg=`{$SelfReg}`> -\
            #endif                                                             -\
                                                                               -\
            ;--- Any comment for this file? ------------------------------     -\
            #if  '{$Comment="<$DEFAULT_FILE_COMMENT>" $$SQx2}' <> ''           -\
               <$CommentFile File=`{$DESTINATION}` Comment=`{$Comment}`>       -\
               <$CommentFile File=`<$@@DEST>`      Comment=`{$Comment}`>       -\
            #endif                                                             -\
                                                                               -\
            ;--- Remember file for the HTML report -----------------------     -\
            #evaluate ^^ ^<$Rexx2AddFileToReport {$?ResetUsed}{$?} NEWDEST=^<$@@DEST>^>^
    #NextId
    #RexxVar RptFileCnt = 0             ;;Currently storing no file information
    #DefineRexx 'Rexx2AddFileToReport'
            ;--- Get Passed Information -----------------------------------------
            @@Src     = '{$SOURCE}'
            @@DstDir  = _filespec('location', '{$NEWDEST}');
            @@Added2  = '{$Add2="<$DEFAULT_ADD2>"}'
    
            ;--- Check that file exists -----------------------------------------
            @@SrcFull = stream(@@Src, 'c', 'query exists');
            if @@SrcFull = '' then
               error('Could not find the file "' || @@Src || '"');
    
            ;--- Get file info --------------------------------------------------
            @@Date    = GetFileTimeStamp(@@SrcFull);
            @@Size    = AddCommasToDecimalNumber(stream(@@SrcFull, 'c', 'query size'));
            @@SrcLocn = _filespec('location', @@SrcFull);
            @@Short   = _filespec('name',     '{$DESTINATION}');
    
            ;--- Clean up directories -------------------------------------------
            if right(@@DstDir, 1) = '\' then
               @@DstDir = left(@@DstDir, length(@@DstDir)-1);
            if right(@@SrcLocn, 1) = '\' then
               @@SrcLocn = left(@@SrcLocn, length(@@SrcLocn)-1);
    
            ;--- Add source filename if it is being renamed ---------------------
            @@ShortS = _filespec('name', @@SrcFull);
            if translate(@@ShortS) <> translate(@@Short) then
               @@SrcLocn = @@SrcLocn || ' (' || @@ShortS || ')';
    
            ;--- Set key for sorting by -----------------------------------------
            #define? WISEINST_HTMLRPT_SORT_BY @@Date    ;;Allow overriding of sort key (should not include null byte)
            @@SortKey = <$WISEINST_HTMLRPT_SORT_BY>;
    
            ;--- Combine (sort key up front) and save ---------------------------
            @@All  = @@SortKey || '0000'x || @@Short || '00'x || @@DstDir || '00'x || @@SrcLocn || '00'x || @@Date || '00'x || @@Size;
            RptFileCnt         = RptFileCnt + 1;
            RptFile.RptFileCnt = @@All;
            RptFile.0          = RptFileCnt;
    #DefineRexx
    
    ;--- AddFileWild (Does an "AddFile()" once for each file --------------------
    #define AddFileWild                                                        \
           <$HereWeAre "{$?MacName} - {$SrcDir}\{$Includes=^*.*^}">           %\
           #evaluate ^^ ^<$AddFileWildRexx {$?ResetUsed}{$?}>^                -\
           <??Vb>
    #NextId
    #define?    DEFAULT_FILE_COMMENT               ;;"None" by default
    #DefineRexx 'AddFileWildRexx'
           ;--- Allow list of masks to be passed seperated by ";" ---------------
           @@MaskList = '{$Includes=^*.*^}'
           @@Searched = @@MaskList
           SrcFiles.0 = 0;
           do  until @@MaskList = ''
               ;--- Split of next mask ------------------------------------------
               parse var @@MaskList @@Mask ';' @@MaskList;
    
               ;--- Now get list of files matching this mask --------------------
               @@Look4   = '{$SrcDir}\' || @@Mask;
               @@Files.0 = 0;
               call _SysFileTree   @@Look4, "@@Files";
               if  @@Files.0 = 0 then
               do
                   ;--- Did not find any files, is this OK? -------------------------
                   if  '{$NONEOK=^N^}' = 'N' then
                       error('No files matched "' || @@Look4 || '"!');
               end;
    
               ;--- Now add this to the source file list ------------------------
               @@SrcCnt = SrcFiles.0
               do  @@I = 1 to @@Files.0
                   ;--- Move the file -------------------------------------------
                   @@SrcCnt          = @@SrcCnt + 1;
                   SrcFiles.@@SrcCnt = @@Files.@@I;
               end;
               SrcFiles.0 = @@SrcCnt;
           end;
    
           ;--- If keyfile supplied, make sure it is valid to do so -------------
           KeyFileUsed = 'N'
           KeyFile     = translate('{$KEYFILE=^^}');
           if  KeyFile <> '' then
           do
               ;--- Must be adding to a component -------------------------------
               if  '{$Add2Type="<$DEFAULT_ADD2TYPE>"}' = '<$IS_FEATURE>' then
               do
                   error('If you want to set the keyfile to be "' || KeyFile || '"', 'then you must add the files to a component (not a feature)');
               end;
           end;
    
           ;--- Create output ---------------------------------------------------
           Vb         = ''
           do  Findex = 1 to SrcFiles.0
               ;--- Have exclude list? ------------------------------------------
               if  '{$EXLIST=^^}' <> '' then
               do
                   ;--- See if this file is in the exclude list -----------------
                   <$Rexx4ExcludeListFileIn EXLIST=^{$EXLIST}^ FILEVAR=^SrcFiles.Findex^ FOUNDVAR=^@@IsExcluded^>
                   if  @@IsExcluded = 'Y' then
                   do
                       ;--- This file is excluded so ignore ---------------------
                       iterate;
                   end
               end;
    
               ;--- Make sure that the Key into the file table is consistant case! ---
               SourceFile = ToLowerCase(SrcFiles.Findex);
    
               ;--- Create VB code to add the file ------------------------------
               if  '{$SelfReg=""}' = '' then
                   @@Sr = ''                              ;;User did not specify
               else
                   @@Sr = '      SelfReg=^{$SelfReg}^'    ;;Only pass if supplied
    
               ShortName = _filespec('name', SrcFiles.Findex);
               Vb = Vb || '<' || '$AddFile1 '
               Vb = Vb || '       SOURCE=^' || SourceFile || '^ '
               Vb = Vb || '  DESTINATION=^{$DestDir}\' || ShortName || '^ '
               Vb = Vb || '         ADD2=^{$Add2="<$DEFAULT_ADD2>"}^ '
               Vb = Vb || '     Add2Type=^{$Add2Type="<$DEFAULT_ADD2TYPE>"}^ '
               Vb = Vb || '   Attributes=^{$Attributes="<$SFATTR_DEFAULT>"}^ '
               Vb = Vb || '      Comment=^{$Comment="<$DEFAULT_FILE_COMMENT>" $$SQx2}^ '
               Vb = Vb || @@Sr;
               Vb = Vb || '><?NewLine>'
    
               ;--- Did user specify a keyfile, if so is this it? ---------------
               if  KeyFile <> '' & KeyFileUsed = 'N' then
               do
                   ;--- User has specified a keyfile (used "*"?) ----------------
                   if  KeyFile = '*' then
                   do
                       ;--- Use 1st file found (User wants any) -----------------
                       KeyFile = translate(ShortName);
                   end;
    
                   ;--- Does this file match the keypath? -----------------------
                   if  KeyFile = translate(ShortName) then
                   do
                       ;--- This is the keyfile (KeyPath is global VB variable) -
                       Vb = Vb || 'HereWeAre "<$HEREWEARE_LOCN>", "SetComponentKeyPath({$Add2})"<?NewLine>'
                       Vb = Vb || 'Ok = <$WiseObj>.SetComponentKeyPath("{$Add2}", KeyPath)<?NewLine>'
                       Vb = Vb || '<$DieIfNotOk><?NewLine>'
                       KeyFileUsed = 'Y'
                   end;
               end;
           end;
    
           ;--- Ensure macro(s) gets expanded -----------------------------------
           Vb = Vb || d2c(10)
    
           ;--- Have exclude list we need to add these files to? ----------------
           if  '{$EXLIST}' <> '' then
           do
               ;--- Add this file to it -------------------------------------
               <$Rexx4ExcludeListAddStem EXLIST=^{$EXLIST}^ FILESTEM="SrcFiles">
           end
    
           ;--- Ensure that if user specified a keyfile that it was used --------
           if  KeyFile <> '' then
           do
               ;--- User has specified a keyfile --------------------------------
               if  KeyFileUsed = 'N' then
               do
                   error('The KeyFile "{$KEYFILE}" was not found.', 'Searched "' || @@Searched || '"');
               end;
           end;
           {$!}
    #DefineRexx
    
    ;--- This Wise call not only buggy, but my replacement macro is probably better ---
    ;**      CommentBlock  /* (Friday 30/03/2001, 15:22:27, by Dennis Bareis) */
    ;**+--------------------------------------------------------------------------
    ;**|;--- Add files (wildcard - Front end to AddWildCard() call) -----------------
    ;**|#define AddFiles                                                 \
    ;**|        <$HereWeAre "{$?MacName} - {$SrcDir}">                  %\
    ;**|        Key = <$WiseObj>.AddWildcard(                            \
    ;**|              "{$FEATURE="<$DEFAULT_FEATURE>"}",                        \
    ;**|              {$CONDITION=^^  $$VBSTR},                          \
    ;**|              "{$Includes=^*.*^}",     ;;Delimiter = ";"         \
    ;**|              "{$Excludes=^^}",        ;;Delimiter = ";"         \
    ;**|              "{$SrcDir}",                                       \
    ;**|              "{$DestDir}",                                      \
    ;**|              {$How="<$SUBDIRECTORIES>"},                        \
    ;**|              {$CompAttr="<$CATTR_DEFAULT>"}                     \
    ;**|        )                                                       %\
    ;**|        <$DieIfKeyInvalid>{$!}
    ;**+--------------------------------------------------------------------------
    ;**                    /* (Friday 30/03/2001, 15:22:27, by Dennis Bareis) */
    
    ;----------------------------------------------------------------------------
    ;--- HTML File Comment ------------------------------------------------------
    ;----------------------------------------------------------------------------
    #RexxVar CmtFileCnt = 0                ;;How many file comments?
    #define CommentFile \
            #evaluate ^^  ^<$Rexx4CommentFile {$?}>^
    #NextId
    #DefineRexx 'Rexx4CommentFile'
       ;--- Increment count of comments -----------------------------------------
       CmtFileCnt = CmtFileCnt + 1
    
       ;--- Create a "Key" for this file ----------------------------------------
       @@Key = "HCF_" || c2x(translate('{$File}'));
    
       ;--- Store the comment ---------------------------------------------------
       call value @@Key, '{$Comment $$Rx'}'
    #DefineRexx
    #define?  WISEINST_HTMLRPT_NO_FILE_COMMENT  &nbsp;
    #DefineRexx 'Rexx4GetFileComment'
       ;--- Get filename --------------------------------------------------------
       @@FileName = {$FileVar};
    
       ;--- First look for comment with destination name (KEY) ------------------
       @@Key = "HCF_" || c2x(translate({$DestDirVarK} || '\' || @@FileName));
       if  symbol(@@Key) = 'VAR' then
           @@Cmt = value(@@Key);
       else
       do
           ;--- First look for comment with destination name (PRETTY) -----------
           @@Key = "HCF_" || c2x(translate({$DestDirVarP} || '\' || @@FileName));
           if  symbol(@@Key) = 'VAR' then
               @@Cmt = value(@@Key);
           else
           do
               ;--- Now look as source specific ---------------------------------
               @@Key = "HCF_" || c2x(translate({$SrcDirVar} || '\' || @@FileName));
               if  symbol(@@Key) = 'VAR' then
                   @@Cmt = value(@@Key);
               else
               do
                   ;--- Now look as short name ----------------------------------
                   @@Key = "HCF_" || c2x(translate(_filespec('name', @@FileName)));
                   if  symbol(@@Key) = 'VAR' then
                       @@Cmt = value(@@Key);
                   else
                   do
                       ;--- Now look for short name without extension -----------
                       @@Key = "HCF_" || c2x(translate(_filespec('withoutextn', _filespec('name', @@FileName))));
                       if  symbol(@@Key) = 'VAR' then
                           @@Cmt = value(@@Key);
                       else
                       do
                           ;--- Now look for just extension match ---------------
                           @@Key = "HCF_" || c2x(translate('.' || _filespec('extn', @@FileName)));
                           if  symbol(@@Key) = 'VAR' then
                               @@Cmt = value(@@Key);
                           else
                           do
                               ;--- There is no comment! ------------------------
                               #ifndef WISEINST_MUST_COMMENT_ALL_FILES
                                   @@Cmt = '<$WISEINST_HTMLRPT_NO_FILE_COMMENT $$SQx2>';
                               #elseif
                                   error('There is no file comment for the', 'file: "' || @@FileName || '"');
                               #endif
                           end;
                       end;
                   end;
               end;
           end;
       end;
    
       ;--- Return the comment --------------------------------------------------
       {$CmtVar} = @@Cmt;
    #DefineRexx
    
    
    ;--- Macros etc to set up for INI entry addition ----------------------------
    #RexxVar IniFileStarted = ''   ;;"" means outside "INIFILE" block
    #RexxVar IniComponent   = ''   ;;Which component controls these entries?
    #RexxVar IniFile        = ''   ;;ShortName of INI file (note, this is NOT a key into the file table, but actual INI name)
    #RexxVar IniDir         = ''   ;;Directory where INI resides (no "[]", example "DIR_QUOTE_LIFE_PGM")
    #define IniFile                                                             \
            ;--- Make sure not already in an INIFILE block -----------------   -\
            <$HereWeAre "{$?MacName} - Start of INI '{$FILE}'">                %\
            #if [IniFileStarted <> '']                                         -\
                #error ^Already in INIFILE "<??IniDir>\<??IniFile>" started at <??IniFileStarted>^  -\
            #endif                                                             -\
            #RexxVar IniFileStarted = ^<?=GetInputFileNameAndLine()>^          -\
                                                                               -\
            ;--- OK, remember details --------------------------------------   -\
            #RexxVar IniFile    = ^{$FILE}^                                    -\
            #RexxVar IniDir     = ^{$DIR}^                                     -\
            #RexxVar IniSection = ^{$SECTION=""}^                              -\
            #RexxVar IniComponent = ^{$Add2="<$DEFAULT_ADD2>"}^                -\
                                                                               -\
            ;--- Now Gain access to the "IniFile" table --------------------   -\
            <$Table "IniFile">                                                 -\
            {$!}
    #define IniSection                                                          \
            ;--- User is indicating the start of a new [section] -----------   -\
            <$HereWeAre "{$?MacName} - Start of INI Section '{$#1}'">          %\
            <$MustBeWithinIniFileBlock>                                        -\
            #RexxVar IniSection = ^{$#1}^                                      -\
            {$!}
    #define /IniFile                                                            \
            ;--- At end of block so end table and clear memory -------------   -\
            <$HereWeAre "{$?MacName} - End of INI '<??IniFile>'">              %\
            <$MustBeWithinIniFileBlock>                                        -\
            <$/Table>                                                          -\
            #RexxVar IniFileStarted = ^^                                       -\
            {$!}
    #define MustBeWithinIniFileBlock                                            \
            #if [IniFileStarted = '']                                          -\
                #error ^You must be within a "IniFile" block to use this macro!^  -\
            #endif                                                             -\
    
    ;--- Macros etc for INI Addition --------------------------------------------
    #define  INIACT_CREATE_OR_UPDATE          0
    #define  INIACT_CREATE_IF_DOESNT_EXIST    1   ;;Never update an existing value!
    #define  INIACT_CREATE_OR_APPEND_COMMASEP 3   ;;Appends to comma delimited list
    #define? INIACT_DEFAULT                  <$INIACT_CREATE_OR_UPDATE>
    #define IniAdd                                                              \
            ;--- Do some validations ---------------------------------------   -\
            <$HereWeAre "{$?MacName} - KEY = {$Key}">                          %\
            <$MustBeWithinIniFileBlock>                                        -\
            #if [IniSection = '']                                              -\
                #error ^You have not defined an INI Section!^                  -\
            #endif                                                             -\
                                                                               -\
            ;--- Add the INI entry to the table ----------------------------   -\
            #evaluate+ ^^ ^DefaultIniKey= 'AddIni<$WiCounter "{$?MacName}">'^  -\
            <$Row                                                               \
                       Key="{$Key}"                                             \
                     Value="{$Value}"                                           \
                    Action="{$Action=^<$INIACT_DEFAULT>^}"                      \
                   IniFile="{$RowKey=^<??DefaultIniKey>^}"                      \
                  FileName="<??IniFile>"                                        \
               DirProperty="<??IniDir>"                                         \
                   Section="<??IniSection>"                                     \
                Component_="<??IniComponent>"                                   \
            >                                                                  -\
            {$!}
    
    
    
    
    ;--- Add Registery Value ----------------------------------------------------
    #define  CURRENT_USER_PUI                 -1      ;;HKEY_
    #define  CLASSES_ROOT                      0      ;;HKEY_
    #define  CURRENT_USER                      1      ;;HKEY_
    #define  LOCAL_MACHINE                     2      ;;HKEY_
    #define  USERS                             3      ;;HKEY_
    #define? HKEY_DEFAULT                             ;;User must override for value to default
    #define  RT_STRING                         0      ;;Type
    #define  RT_EXPANDABLE_STRING              1      ;;Type
    #define  RT_INTEGER                        2      ;;Type
    #define  RT_DWORD                          <$RT_INTEGER>  ;;Called DWORD in regedit
    #define  RT_BINARY                         3      ;;Type
    #define? RT_DEFAULT                        <$RT_STRING>
    #define  RH_CREATE_UPDATE_KEY_AND_VALUE         0      ;;Undocumented (thanks Wise)
    #define  RH_CREATED_IF_MISSING                  1
    #define  RH_DELETE_KEY_AND_SUBKEYS_ON_UNINSTALL 2
    #define  RH_CREATE_AND_DELETE_ON_UNINSTALL      3
    #define  RH_CREATE_EMPTY_KEY                    <$RH_CREATED_IF_MISSING>  ;;Note that names imply 2 different things (thanks Wise)
    #define? RH_DEFAULT                             <$RH_CREATE_UPDATE_KEY_AND_VALUE>
    #define? DEFAULT_REGKEY                    RegKey<$WiCounter "AddRegValue">
    #define AddRegValue                                                         \
            <$HereWeAre "{$?MacName} - {$ValueName=^(Default)^}">              %\
            #if ['{$HKEY=^<$HKEY_DEFAULT>^}' = '']                                -\
                #error ^HKEY parameter can't default until you specify a default!^ -\
            #endif                                                             -\
            KeyPath = <$WiseObj>.AddRegistryValueEx(                            \
                      {$HKEY},                   ;;Hive can default (see above) \
                      "{$Key}",                  ;;Key Part 1                   \
                      "{$ValueName=^^}",         ;;Key Part 2                   \
                      {$Value  $$VBSTR},         ;;The data!                    \
                      {$Type="<$RT_DEFAULT>"},                                  \
                      {$HOW="<$RH_DEFAULT>"},                                   \
                      "{$Add2="<$DEFAULT_ADD2>"}", ;;Feature/Component name     \
                      {$Add2Type="<$DEFAULT_ADD2TYPE>"},                        \
                      PvComponent                                               \
            )                                                                  %\
            <$DieIfKeyInvalid KEYVAR="KeyPath">                                %\
                                                                               -\
            ;--- Need to adjust the generated Registry entry? ------------     -\
            #RexxVar RxRowKey = ^{$RowKey=^<$DEFAULT_REGKEY>^}^                -\
            #if RxRowKey <> ''                                                 -\
                <$HereWeAre "{$?MacName} - Setting Key to: <??RxRowKey>">      %\
                set RegistryTable = <$WiseObj>.WTables("Registry")             %\
                set RegistryRows  = RegistryTable.WRows()                      %\
                set RegistryRow   = RegistryRows.Row(KeyPath)                  %\
                KeyPath           = "<??RxRowKey>"                             %\
                RegistryRow("Registry") = KeyPath                              %\
                set RegistryRow   = Nothing                                    %\
                set RegistryRows  = Nothing                                    %\
                set RegistryTable = Nothing                                    %\
            #endif                                                             -\
                                                                               -\
            ;--- User want this registry entry to be the keypath? --------     -\
            #if ['{$KEYPATH=^N^}' = 'Y']                                       -\
                ;--- User wants to use this registry item as a keypath         -\
                <$HereWeAre "{$?MacName} - This entry is the component keypath">  %\
                Ok = <$WiseObj>.SetComponentKeyPath("{$Add2}", KeyPath)        %\
                <$DieIfNotOk>                                                  %\
            #endif                                                             -\
            {$!}                                                               -\
                                                                               -\
            ;--- Remember this for the HTML report -----------------------     -\
            #evaluate ^^ ^<$Rexx2AddRegToReport {$?ResetUsed}{$?}>^
    #NextId
    #RexxVar RptRegCnt = 0             ;;Currently storing no file information
    #DefineRexx 'Rexx2AddRegToReport'
            ;--- Get Passed Information -----------------------------------------
            @@Hkey = "{$HKEY=^<$HKEY_DEFAULT>^}"
            @@Hkey = word("CURRENT_USER_PU CLASSES_ROOT CURRENT_USER LOCAL_MACHINE USERS", @@Hkey+2);
            @@Key       = "{$Key}"
            @@ValueName = "{$ValueName=^(Default)^}"
            @@Value     = '{$Value $$Sqx2}'
    
            ;--- Combine (using good sort order) and save -----------------------
            @@All  = @@Hkey || '00'x || @@Key || '00'x || @@ValueName || '00'x || @@Value;
            RptRegCnt = RptRegCnt + 1;
            RptReg.RptRegCnt = @@All;
            RptReg.0         = RptRegCnt;
    #DefineRexx
    
    
    
    
    ;--- Add Binary to Binary TABLE ---------------------------------------------
    #define? WISEINST_MAX_BINARY_ENTRIES 100
    #RexxVar RxBinaryCnt = 0
    #(   '<?NewLine>'
       #define AddBinary
               ;--- Generate code to place icon into a VB variable ("ID") -------
               <$HereWeAre "{$?MacName} - {$File}">
               #DependsOn INPUT "{$File}"
               #RexxVar RxBinaryCnt + 1                 ;;Increment counter
               BinaryKey(<??RxBinaryCnt>)  = "{$Key}"   ;;Remember Key
               BinaryFile(<??RxBinaryCnt>) = "{$File}"  ;;Remember File Name
               {$!}
    #)
    
    
    
    ;--- Add ICON to icon table (must be referred to by shortcut or gets "dropped") ---
    #RexxVar   AddIconCnt = 0
    #(   '<?NewLine>'
       #define AddIcon
               ;--- Generate code to place icon into a VB variable ("ID") -------
               <$HereWeAre "{$?MacName} - {$Key=^<?=_filespec('name', "{$File}")>^} : {$File}">
               #DependsOn INPUT "{$File}"
           ;;    #evaluate ^^ ^<$LoadIconIntoVbVariable "{$File}">^
           ;;    <??VbCode>
    
               ;--- Generate VB code to remember the details --------------------
           ;;    '!!! Hack to work around WISE Installer 3.1 Limitations... !!!!!!!!!!
           ;;    set IconTable   = <$WiseObj>.WTables("Icon")
           ;;    set IconRow     = IconTable.NewWRow()
           ;;    IconRow("Name") = "{$Key}"
           ;;    IconRow("Data") = ID
           ;;    set IconRow   = Nothing
           ;;    set IconTable = Nothing
               #evaluate ^^ ^<$AddIconHackRememberDetails KEY=~{$Key}~ FILE=~{$File}~>^
               {$!}
    #)
    #DefineRexx 'AddIconHackRememberDetails'
                ;--- Add to my array --------------------------------------------
                AddIconCnt = AddIconCnt + 1;
                AddIconHack.AddIconCnt.IconKey  = '{$Key}';
                AddIconHack.AddIconCnt.IconFile = '{$File}';
    #DefineRexx
    #DefineRexx 'UpdateMsiForIcons'
                VbCode = "<?NewLine>'!!! Hack to work around Wise 3.1 issues !!!!!<?NewLine>"
                do HackIndex = 1 to AddIconCnt
                   VbCode = VbCode || 'HackIconIntoMsi '
                   VbCode = VbCode || '"' || AddIconHack.HackIndex.IconKey  || '", '
                   VbCode = VbCode || '"' || AddIconHack.HackIndex.IconFile || '", '
                   VbCode = VbCode || '"{$FILE}"<?NewLine>'
                end;
    #DefineRexx
    
    
    ;**      CommentBlock  /* (Friday 16/02/2001, 10:30:52, by Dennis Bareis) */
    ;**+--------------------------------------------------------------------------
    ;**|;--- WISE "FEATURES" PREVENT THIS WORKING
    ;**|;--- Add ICON to icon table (must be referred to by shortcut or gets "dropped") ---
    ;**|#(   '<?NewLine>'
    ;**|   #define AddIcon
    ;**|           ;--- Generate code to place icon into a VB variable ("ID") -------
    ;**|           <$HereWeAre "{$?MacName} - {$Key=^<?=_filespec('name', "{$File}")>^} : {$File}">
    ;**|           #evaluate ^^ ^<$LoadIconIntoVbVariable "{$File}">^
    ;**|           <??VbCode>
    ;**|
    ;**|           ;--- Now Add the loaded icon file into the table -----------------
    ;**|           set IconTable   = <$WiseObj>.WTables("Icon")
    ;**|           set IconRow     = IconTable.NewWRow()
    ;**|           IconRow("Name") = "{$Key}"
    ;**|           IconRow("Data") = ID
    ;**|           set IconRow     = Nothing
    ;**|           {$!}
    ;**|#)
    ;**+--------------------------------------------------------------------------
    ;**                    /* (Friday 16/02/2001, 10:30:52, by Dennis Bareis) */
    
    
    ;--- Add Shortcut -----------------------------------------------------------
    #define? SCD_DEFAULT        <$STARTBAR_PGM_DIR>      ;;Default shortcut dir
    #define  SCT_ADVERTISED     1
    #define  SCT_FOR_FILE       2
    #define  SCT_FOR_CMDLINE    3
    #define? SCT_DEFAULT        <$SCT_FOR_CMDLINE>
    #define  SCW_NORMAL         0
    #define  SCW_MINIMISED      7
    #define  SCW_MAXIMISED      3
    #define  SCW_MINIMIZED      <$SCW_MINIMISED>
    #define  SCW_MAXIMIZED      <$SCW_MAXIMISED>
    #define? SCW_DEFAULT        <$SCW_NORMAL>
    #define AddShortCut                                                        \
            ;--- Handle short cut locations like "ProgramMenuFolder\???\???"  -\
            <$HereWeAre "{$?MacName} - {$Title}">                             %\
            #evaluate ^^ ^<$Rexx4MakeDirTree DIRECTORY="{$ScDir=^<$SCD_DEFAULT>^}">^ -\
            <??Wi>                                                            -\
                                                                              -\
            ;--- Actually create the shortcut ---------------------------     -\
            <?NewLine>                                                        -\
            Key = <$WiseObj>.AddShortCutEx(                                    \
                  {$ScType=^<$SCT_DEFAULT>^},                                  \
                  lcase("{$ScTarget=^^}"),           ;;Not required if ADVERT (Component name etc) \
                  "{$AdvAdd2="<$DEFAULT_FEATURE>"}", ;;Advert? Install what?   \
                  ShortLongSpec({$Title $$VBSTR}),   ;;Shortcut's Name         \
                  "<??WiDirName>",                   ;;Create where (no "[]")? \
                  "{$ScArgs=^^}",                    ;;Shortcut's arguments    \
                  "{$ScDesc=^^}",                    ;;Shortcut's description  \
                  "{$ScWorkDir=^^}",                 ;;Shortcut's work dir     \
                  {$ScHotKey=^0^},                   ;;Shortcut's hot key      \
                  {$ScWinSize=^<$SCW_DEFAULT>^},     ;;Shortcut's Window size  \
                  {$ScIconNumb=^0^},                 ;;Icon # in EXE           \
                  "{$Add2="<$DEFAULT_ADD2>"}",       ;;Feature/Component name  \
                  {$Add2Type="<$DEFAULT_ADD2TYPE>"}, ;;Feature or Component?   \
                  PvComponent                                                  \
            )                                                                 %\
            <$DieIfKeyInvalid>                                                %\
                                                                              -\
            ;--- Need to adjust the generated shortcut? ------------------    -\
            #if '{$ScIconKey=^^}' <> '' | '{$RowKey=^^}' <> ''                -\
                <$HereWeAre "{$?MacName} - Pointing to ICON: {$ScIconKey}">   %\
                set ShortCutTable = <$WiseObj>.WTables("Shortcut")            %\
                set ShortCutRows  = ShortCutTable.WRows()                     %\
                set ShortCutRow   = ShortCutRows.Row(Key)                     %\
                #if ['{$ScIconKey=^^}' <> '']                                 -\
                    ;--- Assign ICON to this shortcut --------------------    -\
                    <$HereWeAre "{$?MacName} - Add Icon: {$ScIconKey}">       -\
                    <?NewLine>                                                -\
                    ShortCutRow("Icon_") = "{$ScIconKey}"<?NewLine>           -\
                #endif                                                        -\
                #if ['{$RowKey=^^}' <> '']                                    -\
                    ;--- Modify the key (as specified by user) -----------    -\
                    <$HereWeAre "{$?MacName} - New Key: {$RowKey}">           -\
                    <?NewLine>                                                -\
                    ShortCutRow("Shortcut") = "{$RowKey}"<?NewLine>           -\
                #endif                                                        -\
                set ShortCutRow   = Nothing                                   %\
                set ShortCutRows  = Nothing                                   %\
                set ShortCutTable = Nothing                                   %\
            #endif                                                            -\
            {$!}                                                              -\
                                                                              -\
            ;--- Remember this for the HTML report -----------------------    -\
            #evaluate ^^ ^<$Rexx2AddScToReport {$?ResetUsed}{$?} DIRALIAS=~<??WiDirName>~>^
    ;**      CommentBlock  /* (Monday 26/11/2001, 14:24:18, by Dennis Bareis) */
    ;**+--------------------------------------------------------------------------
    ;**|#define AddShortCut                                                        \
    ;**|        ;--- Actually create the shortcut ---------------------------     -\
    ;**|        <$HereWeAre "{$?MacName} - {$Title}">                             %\
    ;**|        <?NewLine>                                                        -\
    ;**|        Key = <$WiseObj>.AddShortCutEx(                                    \
    ;**|              {$ScType=^<$SCT_DEFAULT>^},                                  \
    ;**|              lcase("{$ScTarget=^^}"),           ;;Not required if ADVERT (Component name etc) \
    ;**|              "{$AdvAdd2="<$DEFAULT_FEATURE>"}", ;;Advert? Install what?   \
    ;**|              ShortLongSpec({$Title $$VBSTR}),   ;;Shortcut's Name         \
    ;**|              "{$ScDir=^<$SCD_DEFAULT>^}",       ;;Create where?           \
    ;**|              "{$ScArgs=^^}",                    ;;Shortcut's arguments    \
    ;**|              "{$ScDesc=^^}",                    ;;Shortcut's description  \
    ;**|              "{$ScWorkDir=^^}",                 ;;Shortcut's work dir     \
    ;**|              {$ScHotKey=^0^},                   ;;Shortcut's hot key      \
    ;**|              {$ScWinSize=^<$SCW_DEFAULT>^},     ;;Shortcut's Window size  \
    ;**|              {$ScIconNumb=^0^},                 ;;Icon # in EXE           \
    ;**|              "{$Add2="<$DEFAULT_ADD2>"}",       ;;Feature/Component name  \
    ;**|              {$Add2Type="<$DEFAULT_ADD2TYPE>"}, ;;Feature or Component?   \
    ;**|              PvComponent                                                  \
    ;**|        )                                                                 %\
    ;**|        <$DieIfKeyInvalid>                                                %\
    ;**|                                                                          -\
    ;**|        ;--- Need to adjust the generated shortcut? ------------------    -\
    ;**|        #if '{$ScIconKey=^^}' <> '' | '{$RowKey=^^}' <> ''                -\
    ;**|            <$HereWeAre "{$?MacName} - Pointing to ICON: {$ScIconKey}">   %\
    ;**|            set ShortCutTable = <$WiseObj>.WTables("Shortcut")            %\
    ;**|            set ShortCutRows  = ShortCutTable.WRows()                     %\
    ;**|            set ShortCutRow   = ShortCutRows.Row(Key)                     %\
    ;**|            #if ['{$ScIconKey=^^}' <> '']                                 -\
    ;**|                ;--- Assign ICON to this shortcut --------------------    -\
    ;**|                <$HereWeAre "{$?MacName} - Add Icon: {$ScIconKey}">       -\
    ;**|                <?NewLine>                                                -\
    ;**|                ShortCutRow("Icon_") = "{$ScIconKey}"<?NewLine>           -\
    ;**|            #endif                                                        -\
    ;**|            #if ['{$RowKey=^^}' <> '']                                    -\
    ;**|                ;--- Modify the key (as specified by user) -----------    -\
    ;**|                <$HereWeAre "{$?MacName} - New Key: {$RowKey}">           -\
    ;**|                <?NewLine>                                                -\
    ;**|                ShortCutRow("Shortcut") = "{$RowKey}"<?NewLine>           -\
    ;**|            #endif                                                        -\
    ;**|            set ShortCutRow   = Nothing                                   %\
    ;**|            set ShortCutRows  = Nothing                                   %\
    ;**|            set ShortCutTable = Nothing                                   %\
    ;**|        #endif                                                            -\
    ;**|        {$!}                                                              -\
    ;**|                                                                          -\
    ;**|        ;--- Remember this for the HTML report -----------------------    -\
    ;**|        #evaluate ^^ ^<$Rexx2AddScToReport {$?ResetUsed}{$?}>^
    ;**+--------------------------------------------------------------------------
    ;**                    /* (Monday 26/11/2001, 14:24:18, by Dennis Bareis) */
    #NextId
    #RexxVar RptScCnt = 0             ;;Currently storing no file information
    #DefineRexx 'Rexx2AddScToReport'
            ;--- Get Passed Information -----------------------------------------
            @@ScTitle  = '{$Title $$SQx2}'
    ;;;     @@ScDir    = "{$ScDir=^<$STARTBAR_PGM_DIR>^}"
            @@ScDir    = "{$DirAlias}"
            @@ScTarget = "{$ScTarget=^^}"
            @@ScArgs   = "{$ScArgs=^^}"
    
            ;--- Combine (using good sort order) and save -----------------------
            @@All  = @@ScTitle || '00'x || @@ScDir || '00'x || @@ScTarget || '00'x || @@ScArgs;
            RptScCnt = RptScCnt + 1;
            RptSc.RptScCnt = @@All;
            RptSc.0        = RptScCnt;
    #DefineRexx
    
    
    
    ;--- Set environment Variables ----------------------------------------------
    #define    ENV_SET_DURING_INSTALLATION =
    #define    ENV_DELETE_ON_INSTALL       !
    #define    ENV_DELETE_ON_UNINSTALL     -
    #define    ENV_CREATE_IF_NONEXISTANT   +
    #define?   ENV_DEFAULT_HOW             <$ENV_SET_DURING_INSTALLATION><$ENV_DELETE_ON_UNINSTALL>
    #define?   ENV_DEFAULT_AS_SYSTEM_VAR   Y       ;;Y/N
    #define?   ENV_DEFAULT_COMPONENT
    #(   '<?NewLine>'
       #define Environment
               ;--- Work out the modifier required for the env vars location ----
               #if ['{$SYSTEM=^<$ENV_DEFAULT_AS_SYSTEM_VAR>^}' = 'Y']  -\
                   #define+ ENV_SYS  *                                 -\
               #elseif                                                 -\
                   #define+ ENV_SYS                                    -\
               #endif                                                  -\
    
               ;--- Default KEY/Component names and description -----------------
               #define+ ENV_KEY   ENV_VAR_{$NAME}_AT_LINE_<?InputComponentLine>
    
               ;--- Point to The Environment TABLE ------------------------------
               <$HereWeAre "{$?MacName} - {$NAME}">
               set TableEnvironment = <$WiseObj>.WTables("Environment")
    
               ;--- Add Details to the table (create new row) -------------------
               set Row = TableEnvironment.NewWRow()
               Row("Environment") = "{$Key=^<$ENV_KEY>^}"
               Row("Name")        = "<$ENV_SYS>{$HOW=^<$ENV_DEFAULT_HOW>^}{$NAME}"
               Row("Value")       = "{$Value}"
    
               ;--- What component is this being added to (if default then create component) ---
               #if ['{$Component=^<$ENV_DEFAULT_COMPONENT>^}' = '']
                   #error ^You must supply the component name the environment variable is being added to!^
               #endif
    
               ;--- Used supplied component's name ------------------------------
               Row("Component_") = "{$Component}"
               set Row              = Nothing   ;;Release object
               set TableEnvironment = Nothing   ;;Release object
               {$!}
    #)
    
    
    ;--- Update PATH (type variables) -------------------------------------------
    #(   '<?NewLine>'
       #define Path
               ;--- How is variable updated -------------------------------------
               #if ['{$ATEND=^Y^}' = 'Y']           -\
                   #define+ ENV_POS  [~];{$PATH}    -\
               #elseif                              -\
                   #define+ ENV_POS  {$PATH};[~]    -\
               #endif                               -\
    
               ;--- Point to The Environment TABLE ------------------------------
               <$HereWeAre "{$?MacName}: Setting PATH variable '{$NAME=^PATH^}'">
               <$Environment NAME=~{$NAME=^PATH^}~ VALUE=^<$ENV_POS>^ {$?}>
    #)
    
    
    ;--- Macro(s) to simplify definition of "DIRECTORY ALIASES" -----------------
    ;**      CommentBlock  /* (Thursday 03/05/2001, 10:01:22, by Dennis Bareis) */
    ;**+--------------------------------------------------------------------------
    ;**|#define Directory                                                 \
    ;**|        <$HereWeAre "{$?MacName} - '{$Name}'">                   %\
    ;**|        TmpText1 = "{$SubDir=@<$ProductName>@}"                  %\
    ;**|        TmpText1 = ShortLongSpec(TmpText1)                       %\
    ;**|        <$TABLE "Directory">                                     -\
    ;**|           <$Row                                                  \
    ;**|                      Directory="{$Name}"                         \
    ;**|               Directory_Parent="{$Parent=^ProgramFilesFolder^}"  \
    ;**|;;;;                 DefaultDir="{$SubDir=^<$ProductName>^}"      \
    ;**|                     DefaultDir=^<$VBIMBED STAT=~TmpText1~>^      \
    ;**|           >                                                     -\
    ;**|        <$/TABLE>                                                -\
    ;**|                                                                 -\
    ;**|        ;--- Define a macro which refers to this directory ----  -\
    ;**|        #define {$Name} [{$Name}]                                -\
    ;**|        {$!}
    ;**+--------------------------------------------------------------------------
    ;**                    /* (Thursday 03/05/2001, 10:01:22, by Dennis Bareis) */
    #define Directory                                                      \
            <$HereWeAre "{$?MacName} - '{$Name}'">                        %\
            <$TABLE "Directory">                                          -\
               #if ['{$VALUE=^^}' = '']                                   -\
                   ;--- Just simple definition ------------------------   -\
                   TmpText1 = "{$SubDir=@<$ProductName>@}"                %\
                   TmpText1 = ShortLongSpec(TmpText1)                     %\
                   <$Row                                                   \
                              Directory="{$Name}"                          \
                       Directory_Parent="{$Parent=^ProgramFilesFolder^}"   \
                            DefaultDir=^<$VBIMBED STAT=~TmpText1~>^        \
                   >                                                      -\
               #elseif                                                    -\
                   ;--- Create "template" directory entry -------------   -\
                   <$Row                                                   \
                              Directory="{$Name}"                          \
                       Directory_Parent="TARGETDIR" ;;Value doesn't matter     \
                             DefaultDir=^See_Prop.Tbl|See Property - {$Name}^  \
                   >                                                      -\
                                                                          -\
                   ;--- Now Set the value for the above entry! --------   -\
                   <$SetProperty NAME="{$Name}" VALUE="{$Value}">         %\
               #endif                                                     -\
            <$/TABLE>                                                     -\
                                                                          -\
            ;--- Define a macro which refers to this directory --------   -\
            #define {$Name} [{$Name}]                                     -\
            {$!}
    #define SetDirectoryTextCa                                                  \
            ;--- Create Custom Action to set directory to specific value ---   -\
            <$HereWeAre "{$?MacName} - '{$Directory}' (set with Custom Action)"> %\
            #evaluate+ ^CA_NUMB^     ^'<$WiCounter "{$?MacName}">'^            -\
            #define+    CA_LONG  CA_SetFullDirName_<$CA_NUMB>                  -\
            <$TABLE "CustomAction">                                            -\
               <$Row                                                            \
                   Source="{$Directory}"                                        \
                   Target="{$Text}"                                             \
                   Action="<$CA_LONG>"                                          \
                     Type="35"              ;;Assign text to directory          \
               >                                                               -\
            <$/TABLE>                                                          -\
                                                                               -\
            ;--- Make sure the directory has (or is) created! -------------    -\
            #ifndef {$Directory}                                               -\
               ;--- Create the directory as the user hasn't ---------------    -\
               <$Directory  NAME=^{$Directory}^ SubDir=^SeeCa35.<$CA_NUMB>|See <$CA_LONG>^>  -\
            #endif                                                             -\
            {$!}
    
    
    ;--- Macro to simplify definition of SERVICEs -------------------------------
    #define ServiceInstall                                                      \
            <$HereWeAre "{$?MacName} - '{$Name}'">                             %\
            <$TABLE "ServiceInstall">                                          -\
               <$Row                                                            \
                              Name="{$Name}"                                    \
                       DisplayName="{$DisplayName=~~}"                          \
                    ServiceInstall="{$ServiceInstall}"                          \
                       ServiceType="<$VBIMBED STAT=@{$ServiceType=~<$SERVTYPE_DEFAULT>~}@>"   \
                         StartType="<$VBIMBED STAT=@{$StartType=~<$SERVSTART_DEFAULT>~}@>"    \
                      ErrorControl="<$VBIMBED STAT=@{$ErrorControl=~<$SERVERROR_DEFAULT>~}@>" \
                    LoadOrderGroup="{$LoadOrderGroup=~~}"                       \
                      Dependencies="{$Dependencies=~~}"   ;;Syntax NOT straightforward, read doco! \
                         StartName="{$StartName=~~}"                            \
                          Password="{$Password=~~}"                             \
                         Arguments="{$Arguments=~~}"                            \
                        Component_="{$Add2=^<$DEFAULT_ADD2>^}"                  \
                       Description="{$Description=~<?=space(GetInputFileNameAndLine())>~}" \
               >                                                     -\
            <$/TABLE>                                                -\
            {$!}
    #define  SERVTYPE_WIN32_OWN_PROCESS    &H00000010
    #define  SERVTYPE_WIN32_SHARE_PROCESS  &H00000020
    #define  SERVTYPE_INTERACTIVE_PROCESS  &H00000100   ;;Interacts with desktop
    #define  SERVTYPE_KERNEL_DRIVER        &H00000001   ::MSI Doco says unsupported
    #define  SERVTYPE_FILE_SYSTEM_DRIVER   &H00000002   ::MSI Doco says unsupported
    #define? SERVTYPE_DEFAULT              <$SERVTYPE_WIN32_OWN_PROCESS>+<$SERVTYPE_INTERACTIVE_PROCESS>
    #define  SERVSTART_AUTO_IN_STARTUP     &H00000002
    #define  SERVSTART_ON_DEMAND           &H00000003
    #define  SERVSTART_DISABLED            &H00000004
    #define  SERVSTART_DRIVER_BOOT_START   &H00000000   ;;For device driver only
    #define  SERVSTART_DRIVER_SYSTEM_START &H00000001   ;;For device driver only
    #define? SERVSTART_DEFAULT             <$SERVSTART_AUTO_IN_STARTUP>
    #define  SERVERROR_IGNORE              &H00000000
    #define  SERVERROR_NORMAL              &H00000001
    #define  SERVERROR_CRITICAL            &H00000003
    #define? SERVERROR_DEFAULT             <$SERVERROR_CRITICAL>
    
    
    ;--- Macro to simplify definition of SERVICEs -------------------------------
    #define ServiceControl                                                      \
            <$HereWeAre "{$?MacName} - '{$Name}'">                             %\
            #evaluate+ ^^ ^DefaultScKey= 'ServControl<$WiCounter "{$?MacName}">'^  -\
            <$TABLE "ServiceControl">                                          -\
               <$Row                                                            \
                   ServiceControl="{$ServiceControl=~<??DefaultScKey>~}"        \
                             Name="{$Name}"                                     \
                            Event="<$VBIMBED STAT=@{$Event}@>"                  \
                        Arguments="{$Arguments=~~}" ;;Arguments should be seperated with "[~]"! \
                             Wait="{$Wait=~<$SERVWAIT_DEFAULT>~}"               \
                       Component_="{$Add2=^<$DEFAULT_ADD2>^}"                   \
               >                                                               -\
            <$/TABLE>                                                          -\
            {$!}
    #define  SERVEVENT_I_START          &H001
    #define  SERVEVENT_I_STOP           &H002
    #define  SERVEVENT_I_DELETE         &H008
    #define  SERVEVENT_UI_START         &H010
    #define  SERVEVENT_UI_STOP          &H020
    #define  SERVEVENT_UI_DELETE        &H080
    #define  SERVWAIT_FOR_SERVICE_START 1
    #define  SERVWAIT_FOR_PENDING       0
    #define? SERVWAIT_DEFAULT           <$SERVWAIT_FOR_SERVICE_START>
    
    
    
    ;----------------------------------------------------------------------------
    ;--- Define TABLE -----------------------------------------------------------
    ;----------------------------------------------------------------------------
    #RexxVar InTable = ''
    #define /Table                                                              \
            set CurrentTable = Nothing    '/Table                              %\
            set CurrentRows  = Nothing                                         %\
            #RexxVar InTable = ''
    
    #define Table                                                               \
            ;--- Make sure not already in a table ---                          -\
            #if ['<??InTable>' <> '']                                          -\
                #Error ^Already in table "<??InTable>" started at <??InTableStarted>^  -\
            #endif                                                             -\
                                                                               -\
            ;--- OK, remember details ---------------                          -\
            #RexxVar InTableStarted = ^<?=GetInputFileNameAndLine()>^          -\
            #RexxVar InTable        = ^{$#1}^                                  -\
                                                                               -\
            ;--- Now generate VbScript to access table ---                     -\
            <?NewLine>                                                         -\
            <$HereWeAre =^{$?MacName} - '{$#1}'^>                              %\
            set CurrentTable = <$WiseObj>.WTables("{$#1}")   ;;Generates runtime error if table does not exist  %\
            set CurrentRows  = CurrentTable.WRows()<?NewLine>
    #define MustBeWithinTableMacro                                    \
            ;--- Make sure not already in a table ---                -\
            #if ['<??InTable>' = '']                                 -\
                #Error ^You must be in a table to use this macro!^   -\
            #endif
    
    ;--- Update/Create Row Macro (to update pass key as unnamed parameter) ------
    #define Row                                                                 \
            ;--- Generate code to create a new row ------------                -\
            <$MustBeWithinTableMacro>                                          -\
            <?NewLine>                                                         -\
            #if    ['{$#1=^!NEW!^}' = '!NEW!']                                 -\
                   ;--- Create a new row ----------------------                -\
                   <$HereWeAre =^{$?MacName} - New Record^>                    %\
                   set CurrentRow  = CurrentTable.NewWRow()                    %\
            #elseif                                                            -\
                   <$HereWeAre =^{$?MacName} - KEY='{$#1}'^>                   %\
                   set CurrentRow = CurrentRows.Row("{$#1}")                   %\
            #endif                                                             -\
                                                                               -\
            ;--- Update the fields (Invalid Field name will cause runtime error) --- -\
            #evaluate ^^ ^<$RexxUpdateColumns {$?}>^  ;;VbCode <- Stuff        -\
            <??VbCode>
    #define Row?                                                                \
            ;--- Generate code to create a new row ------------                -\
            <$MustBeWithinTableMacro>                                          -\
            <?NewLine>                                                         -\
            <$HereWeAre =^{$?MacName} - KEY='{$#1}'^>                          %\
            set CurrentRow = GetTableRow("", "{$#1}")                          %\
            if CurrentRow Is Nothing then                                      %\
               <$HereWeAre =^{$?MacName} - Non-existant row not updated'^ VBCMT="N"> %\
            else                                                               %\
               ;--- Update cols (Inv Field name will cause runtime error) ---  -\
               #evaluate ^^ ^<$RexxUpdateColumns {$?}>^  ;;VbCode <- Stuff     -\
               <??VbCode>                                                      -\
            end if
    #DefineRexx RexxUpdateColumns
                ;--- Create rexx stem from passed information -------------------
                {$??}        ;;Allows access to ROW/VALUE information
    
                ;--- Now Create VB code to update the supplied columns ----------
                VbCode = '';
                do Field = 1 to MP.0
                   ;--- The data may be for a binary field ----------------------
                   FldVal = MP.Field.MpValue
                   if  left(FldVal, 5) \== "@Bin(" | right(FldVal, 1) <> ')' then
                       VbCode = VbCode || 'CurrentRow("' || MP.Field.MpName || '") = "' || ReplaceString(FldVal, '"', '""') || '"<?x0A>'
                   else
                   do
                       ;--- User wants to set a binary field --------------------
                       FldFile = substr(FldVal, 6, length(FldVal)-6);
                       VbCode = VbCode || 'set BinCol = CurrentRow.WColumns("' || MP.Field.MpName || '")<?x0A>'
                       VbCode = VbCode || 'BinCol.AccessBinaryData 0, "' || FldFile || '", true<?x0A>'
                   end;
                end;
                VbCode = VbCode || 'set CurrentRow = Nothing<?x0A>'
    #DefineRexx
    
    ;--- Delete all current records in table ------------------------------------
    #define DeleteAllRows                                                       \
            ;--- Generate code to delete all rows of table ---                 -\
            <$MustBeWithinTableMacro>                                          -\
            <$HereWeAre "{$?MacName}">                                         %\
            for each CurrentRow in CurrentRows                                 %\
                CurrentRows.Delete CurrentRow, FALSE                           %\
            next
    
    ;--- Delete Row by KEY ------------------------------------------------------
    #define DeleteRow                                                           \
            ;--- Generate code to delete specific row ---                      -\
            <$MustBeWithinTableMacro>                                          -\
            <$HereWeAre "{$?MacName} - {$#1}">                                 %\
            CurrentRows.DeleteKeyRow "{$#1}", FALSE{$!}
    
    
    ;############################################################################
    ;### Can be used to name a specific dir tree (and make blank) ###############
    ;############################################################################
    #NextId
    #(
       #define DirectoryTree
    
       ;--- Create the appropriate "Directory" table entries --------------------
       #evaluate "" ^<$Rexx4MakeDirTree {$?}>^
       <??Wi>
    
       ;--- Now create a blank folder if that is required -----------------------
       #if ['{$MAKE='Y'}' = 'N']
           ;--- Need to create a component? -------------------------------------
           #if ['{$ADD2=''}' <> '']
               #define+ @@ADD2 {$ADD2}      ;;User supplied component name
           #elseif
               ;--- Need to create the component --------------------------------
               #define+ @@ADD2 _DIRTREE_<??WIDIRNAME>
               <$AddComponent NAME="<$@@ADD2>" DestDir="<??WIDIRNAME>">
           #endif
    
           ;--- Create the folder creation table entry --------------------------
           <$TABLE "CreateFolder">
               <$Row Directory_="<??WIDIRNAME>" Component_="<$@@ADD2>">
           <$/TABLE>
       #endif
    #)
    
    
    ;############################################################################
    ;### Rexx4MakeDirTree - Use "Directory" command to define dir "tree" ########
    ;############################################################################
    #NextId
    #define? DEFAULT_DIR_ROOT C:                 ;;No terminating slash (can be as long as you like)!
    #RexxVar @@PrevDl = ''                       ;;Previous drive letter used
    #evaluate ''   ^call GetIdPrepare 'MakeDirTree'^
    #DefineRexx 'Rexx4MakeDirTree'
       ;--- Start DEBUG ---------------------------------------------------------
       call Debug 'Rexx4MakeDirTree()'
       call DebugIndent 1
    
       ;--- Does user have any preference for the name of the last part of directory? ---
       @@Name = '{$Name=^^}';
    
       ;--- Get directory -------------------------------------------------------
       @@DirO = '{$Directory}'         ;;Original copy (no changes)
                #define ERRDIR 'The directory "' || @@DirO || '" is invalid!'
       if  right(@@DirO, 1) <> '\' then
           @@DirO = @@DirO || '\'
    
    
       ;--- Allow specification of an alias (as prefix to directory) ------------
       if  left(@@DirO, 1) = '{' then
       do
           ;--- Not allowed to also use NAME parameter! -------------------------
           if  @@Name <> '' then
               error('You used the "{name}dir" format AND used the NAME parameter ("' || @@Name || '")', <$ERRDIR>);
    
           ;--- Use the prefix as an alias --------------------------------------
           call Debug 'The directory "' || @@DirO || '" has a NAME as a prefix!'
           parse var @@DirO '{' @@Name '}' @@Dir;
           if  @@Dir = '' then
               error('Incorrectly formatted "{name}dir" reference?', <$ERRDIR>);
           @@DirO = @@Dir;
       end;
    
       ;--- More debug info -----------------------------------------------------
       call Debug 'INPUTS'
       call Debug '~~~~~~'
       call Debug 'DIRECTORY: ' || @@DirO;
       call Debug 'NAME     : ' || @@Name;
       call Debug ''
    
       ;--- See if we can translate all or part of the name ---------------------
       call Debug 'See if we can find a directory alias for start of directory'
       call DebugIndent 1
       @@Dir     = @@DirO;
       @@DirTest = @@Dir;
       do  while @@DirTest <> ''
           ;--- Remove any terminating slash ------------------------------------
           if  right(@@DirTest, 1) = '\' then
               @@DirTest = left(@@DirTest, length(@@DirTest)-1);
    
           ;--- See if we match on the directory --------------------------------
           call Debug 'Look at: ' || @@DirTest;
           @@Key = 'UDIR2WIDIR_' || c2x(translate(@@DirTest));
           if  symbol(@@Key) = 'VAR' then
           do
               ;--- Work out the new name ---------------------------------------
               @@Dir = '[' || value(@@Key) || ']' || substr(@@Dir, length(@@DirTest)+1);
               call Debug 'New DIR: ' || @@Dir;
               leave;
           end;
    
           ;--- No match so remove right most part of directory -----------------
           @@SPos = lastpos('\', @@DirTest);
           if  @@SPos = 0 then
               @@DirTest = '';
           else
               @@DirTest = left(@@DirTest, @@SPos-1);
       end;
       call DebugIndent -1
    
       ;--- Lets do any defined mapping (mapping order highly significant) --
       call Debug 'Do any defined directory mapping (' || DirTreeFrom.0 || ' items)'
       call DebugIndent 1
       @@DirU = translate(@@Dir);
       do  @@I = 1 to DirTreeFrom.0  ;;Note we DON'T exit loop early on match!
           ;--- See if a match ----------------------------------------------
           call Debug 'Does "' || @@DirU || '" begin with "' || DirTreeFrom.@@I || '"?'
           if  abbrev(@@DirU, DirTreeFrom.@@I) then
           do
               ;--- Have a match --------------------------------------------
               @@Dir  = DirTreeTo.@@I || substr(@@Dir, length(DirTreeFrom.@@I)+1)
               @@DirU = translate(@@Dir);
               call Debug 'YES! Translated to "' || @@DirU || '"'
           end;
       end;
       call DebugIndent -1
       @@DirAfterMapping = @@Dir;
    
       ;--- If the item has a trailing slash then remove it ---------------------
       if  right(@@Dir, 1) = '\' then
           @@Dir = left(@@Dir, length(@@Dir)-1);
    
       ;--- Assume OK as is if can't find a '\' ---------------------------------
       WI = ''                          ;;Caller expects this to hold ".WI" code
       if  pos('\', @@Dir) = 0 & substr(@@Dir, 2, 1) <> ':' then
       do
           ;--- Only a single component, Get the "NAME" -------------------------
           call Debug 'Only a single directory component assume it''s an alias'
           if  left(@@Dir, 1) = '[' then
           do
               ;--- Extract the name --------------------------------------------
               parse var @@Dir '[' @@Dir ']' @@Crap;
               if  @@Dir = '' | @@Crap <> '' then
                   error('Incorrectly formatted [dir] reference?', <$ERRDIR>);
           end;
           WIDIRNAME = @@Dir;
       end;
       else
       do
           ;--- See if starts with "\" ------------------------------------------
           if  left(@@Dir, 1) = '\' then
           do
               ;--- Add the prefix ----------------------------------------------
               @@Dir = '<$DEFAULT_DIR_ROOT>' || @@Dir;
               call Debug 'Adding "DEFAULT_DIR_ROOT" to give:' || @@Dir;
           end;
    
           ;--- Strip off any drive letter --------------------------------------
           if  substr(@@Dir, 2, 1) <> ':' then
               @@Dl = '';
           else
           do
               ;--- Has drive letter attached -----------------------------------
               @@Dl  = translate(left(@@Dir, 1));
               @@Dir = substr(@@Dir, 3);
           end;
    
           ;--- If there was a driver letter then "create" it if required -------
           if  @@Dl <> '' then
           do
               ;--- Create the first time we see a specific letter --------------
               @@Dl     = translate(@@Dl);
               if  @@Name = '' | @@Dir <> '' then
                   @@DlName = "_Drive" || @@Dl;  ;;If had name it is meant for the last bit...
               else
               do
                   @@DlName = @@Name;
                   @@Name   = '';          ;;Mark used
               end;
               if pos(@@Dl, @@PrevDl) = 0 then
               do
                   ;--- Need to define! -----------------------------------------
                   call Debug 'Defining the drive letter "' || @@Dl || '" as "' || @@DlName || '"'
    
                   WI = WI || '<' || '$Directory NAME=^' || @@DlName || '^ VALUE=^' || @@Dl || ':\^>' || d2c(10);
                   @@PrevDl = @@PrevDl || @@DL
    
                   ;--- Remember how to translate user to MSI directory bit -----
                   @@UserDir = @@Dl || ':'
                   @@Key = 'UDIR2WIDIR_' || c2x(@@UserDir);
                   call value @@Key, @@DlName;
                   @@Key = 'WIDIR2UDIR_' || c2x(translate(@@DlName));
                   call value @@Key, @@UserDir;    ;;USER DIR (c:) by directory name as key
                   @@Key = 'WIDIR2UDIR_MAPPED_' || c2x(translate(@@DlName));
                   call value @@Key, @@UserDir;    ;;USER DIR (c:) by directory name as key
               end;
    
               ;--- Now use this as a base --------------------------------------
               @@Dir = '[' || @@DlName || ']\' || @@Dir;
           end;
    
           ;--- Extract the BASE (Must start with '[' and end with  ']') --------
           call Debug 'Extracting the BASE from "' || @@Dir || '"'
           parse var @@Dir @@Base '\' @@Dir;
           @@BaseO = @@Base;
           parse var @@Base '[' @@Base ']' @@Crap;
           if  @@Base = '' | @@Crap <> '' then
               error('The base of "' || @@BaseO || '" is invalid (expect "[base]")', <$ERRDIR>);
    
           ;--- Anything to do? -------------------------------------------------
           if  @@Dir = '' then
           do
               ;--- The base is all there is ------------------------------------
               WIDIRNAME = @@Base;
           end;
       else
       do
           ;--- Now work through the tree ---------------------------------------
           call Debug 'Work through the tree "' || @@Dir || '" creating any required directories'
           call DebugIndent 1
           @@BitName = '';
           @@BitCnt  = 0;
           do  while @@Dir <> ''
               ;--- Get Next "bit" of the tree ----------------------------------
               parse var @@Dir @@Bit '\' @@Dir;
               if @@Bit = '' then
                   iterate;                    ;;"\\" etc
               @@BitCnt = @@BitCnt + 1;
    
               ;--- Is this the last bit? If so user have a preference for a name? ---
               if  @@Dir = '' & @@Name <> '' then
               do
                   ;--- User wants a specific key used --------------------------
                   @@BitName = @@Name;
                   @@Name    = '';         ;;Mark as used
               end;
               else
               do
                   ;--- What will we call this directory (it's key) -------------
                   @@BitName = @@Base || '_' || translate(@@Bit);
    
                   ;--- Ensure name not too long and only has valid characters --
                   @@BitName = GetId('MakeDirTree', 'MAXCHARS', @@BitName, '_.', 60)
    
                   ;--- Always start with "_" -----------------------------------
               ;;if  @@BitCnt = 1 then
                       @@BitName = '_' || @@BitName;   ;;This is a trick (be careful replacing the prefix)
               end;
    
               ;--- Don't make items previously made ----------------------------
    ;;           @@Marker = '@@' || @@BitName;       ;;Name of macro which indicates we have already make this component
    ;;           if  symbol(@@Marker) = 'LIT' then
    ;;           do
    ;;               ;--- Mark as made --------------------------------------------
    ;;               call value @@Marker, '';
    
                   ;--- Generate the "Directory" command ------------------------
                   call Debug 'Directory "' || @@Bit || '" being named "' || @@BitName || '"'
                   WI = WI || '<' || '$Directory NAME=^' || @@BitName || '^ PARENT=^' || @@Base || '^ SUBDIR=^' || @@Bit || '^>' || d2c(10);
    
                   ;--- Work out what the original user directory was and save the mapping ---
                   @@UserDir = left(@@DirO, length(@@DirO)-length(@@Dir))
                   if  right(@@UserDir, 1) = '\' then
                       @@UserDir = left(@@UserDir, length(@@UserDir)-1);
                   @@Key = 'UDIR2WIDIR_' || c2x(translate(@@UserDir));
                   call value @@Key, @@BitName;    ;;DIRNAME by user directory as key
    
                   ;--- Now Save directory name as KEY to user dir --------------
                   @@Key = 'WIDIR2UDIR_' || c2x(translate(@@BitName));
                   call value @@Key, @@UserDir;    ;;USER DIR (c:\a\b) by directory name as key
    
                   ;--- Now Save directory name as KEY to user dir (mapped) -----
                   @@Key = 'WIDIR2UDIR_MAPPED_' || c2x(translate(@@BitName));
                   @@UserDirM = left(@@DirAfterMapping, length(@@DirAfterMapping)-length(@@Dir))
                   if  right(@@UserDirM, 1) = '\' then
                       @@UserDirM = left(@@UserDirM, length(@@UserDirM)-1);
                   call value @@Key, @@UserDirM;    ;;USER DIR (c:\a\b) by directory name as key
    ;;           end;
    
               ;--- Now have a new "Parent" (base) ------------------------------
               @@Base = @@BitName;
           end;
           WIDIRNAME = @@BitName;                     ;;Key Name of last dir
           call DebugIndent -1
       end;
       end
       WIDIRREF  = '[' || WIDIRNAME || ']';           ;;Ref to key of last/only dir
    
       ;--- Do "NAME" validation ------------------------------------------------
       if  @@Name <> '' then
           error('Could not name "' || @@DirO || '"', 'The NAME "' || @@Name || '" was not applied (already named "' || WIDIRNAME || '")');
    
       ;--- END   DEBUG ---------------------------------------------------------
       call Debug ''
       call Debug 'OUTPUTS'
       call Debug '~~~~~~~'
       call Debug 'WIDIRNAME: ' || WIDIRNAME;
       call Debug 'WIDIRREF : ' || WIDIRREF;
       call DebugIndent -1
    
       ;=========================================================================
       ;=== OUTPUTS from this rexx ==============================================
       ;=========================================================================
       ; WI        : Contains any required "DIRECTORY" commands to build
       ;             the directory
       ; WIDIRNAME : The key for this directory.
       ; WIDIRREF  : Reference to the "[key]" for this directory.
       ;=========================================================================
    #DefineRexx
    
    
    ;--- Define directory tree mappings -----------------------------------------
    #NextId
    #RexxVar DirTreeFrom.0 = 0
    #RexxVar DirTreeTo.0   = 0
    #DefineRexx 'Map1Dir'
       @@Cnt             = DirTreeFrom.0 + 1;
       DirTreeFrom.@@Cnt = translate('{$#1}');
       DirTreeTo.@@Cnt   = '{$#2}';
       DirTreeFrom.0     = @@Cnt
       DirTreeTo.0       = @@Cnt
    #DefineRexx
    ;--- Define the initial mappings available ----------------------------------
    #DefineRexx ''
        ;--- Allow User to Insert (Before) --------------------------------------
        #define? WISEINST_DTMAPPING_BEFORE
        <$WISEINST_DTMAPPING_BEFORE>
    
        ;--- Map to some standard folder names ----------------------------------
        #ifndef WISEINST_DTMAPPING_NO_STANDARD
           ;--- User did not disable the generation of standard mappings --------
           <$Map1Dir "C:\Program Files\" "[ProgramFilesFolder]\">
           <$Map1Dir "C:\Windows\"       "[WindowsFolder]\">
           <$Map1Dir "C:\WinNT\"         "[WindowsFolder]\">
        #endif
    
        ;--- Example of mapping one drive to another ----------------------------
    ;;;;<$Map1Dir "C:\"  "D:\">
    
        ;--- Allow User to Insert (After) ---------------------------------------
        #define? WISEINST_DTMAPPING_AFTER
        <$WISEINST_DTMAPPING_AFTER>
    #DefineRexx
    
    
    
    
    
    ;############################################################################
    ;### SCHEDULE STUFF #########################################################
    ;############################################################################
    
    
    ;--- Give user some control -------------------------------------------------
    #define? WISEINST_SCHEDULE_JT_EXE_NAME       MS_JT.EXE  ;;Allow user to alter name or add path (no path by default - assume in "PATH" envvar)
    #define? WISEINST_SCHEDULE_CA_TYPE           1030       ;;6=VBS + 1024=Deferred
    #define? WISEINST_SCHEDULE_INSTALL_CA_WHEN   5271
    #define? WISEINST_SCHEDULE_INSTALL_CA_COND   not Installed
    #define? WISEINST_SCHEDULE_UNINSTALL_CA_WHEN 5272
    #define? WISEINST_SCHEDULE_UNINSTALL_CA_COND Installed and REMOVE = "ALL"
    
    ;--- Create start/End Schedule macros ---------------------------------------
    #RexxVar InSchedule     = ''                             ;;Init state
    #RexxVar ScheduleNumber = '0'                            ;;Init counter
    #( ''
       ;--- Name Macro ----------------------------------------------------------
       #define Schedule
    
       ;--- Say what we are doing -----------------------------------------------
       <$HereWeAre "{$?MacName} - {$#1}">
    
       ;--- Check for invalid nesting -------------------------------------------
       #if ['<??InSchedule>' <> '']
           #error ^Already in Schedule "<??InSchedule>" started at <??InScheduleStarted>^
       #endif
    
       ;--- OK Remember details (#1 = Name of JOB) ------------------------------
       #RexxVar InScheduleStarted = ^<?=GetInputFileNameAndLine()>^
       #RexxVar InSchedule        = '{$#1}'
       #RexxVar ScheduleNumber + 1
    
       ;--- Hold output ---------------------------------------------------------
       #OutputHold
    #)
    #DefineRexx HANDLE_SCHEDULE_SPEC
       ;--- Convert to one long space seperated line ----------------------------
       ScheduleSpec = ReplaceString(HeldOutput,   d2c(13) || d2c(10), ' ');
       ScheduleSpec = ReplaceString(ScheduleSpec, d2c(10),            ' ');
    
       ;--- Remember details ----------------------------------------------------
       ScheduleList_NAME.ScheduleNumber = InSchedule
       ScheduleList_SPEC.ScheduleNumber = ScheduleSpec
    
       ;--- We don't want to output anything ------------------------------------
       HeldOutput = ''
    #DefineRexx
    #( ''
       ;--- Name Macro (can't use "HereWeAre" macro as it will generate into schedule spec) ---
       #define /Schedule
    
       ;--- Check for invalid nesting -------------------------------------------
       #if ['<??InSchedule>' = '']
           #error ^You have not started a schedule!^
       #endif
    
       ;--- Stop capturing output and capture as one line line ------------------
       #outputHold 'HANDLE_SCHEDULE_SPEC'
    
       ;--- End of schedule -----------------------------------------------------
       #RexxVar InSchedule = ''
    #)
    
    ;--- Want the generated short name ------------------------------------------
    #DefineRexx ''
       MsiShortName = _filespec('name', '<$GENERATE_MSI>')
    #DefineRexx
    
    ;--- Define VBSCRIPT which creates/deletes the schedule jobs ----------------
    #( '<?NewLine>'
       ;--- Name Macro ----------------------------------------------------------
       #define SCHEDULE_VBSCRIPT_START
    
       ;--- Start of the VB program ---------------------------------------------
       '                                 ;;Comments also show up in log (at least some)
       '
       '************************************************
       '************[ Code autogenerated  ]*************
       '************************************************
       ' Generator   : WISEINST.WIH version <$WISEINST_VERSION>
       ' JT.EXE Name : "<$WISEINST_SCHEDULE_JT_EXE_NAME>"
       ' PRODUCT NAME: <$ProductName>
       ' PRODUCT  VER: <$ProductVersion>
       ' PRODUCT  MSI: <??MsiShortName>
       '************************************************
       ' When called as a CA and MSI logging is turned
       ' on debug output will go to the log.
       '
       ' The JT.EXE program named above must exist on the
       ' destination machine and if no path supplied must
       ' be in a path specified in the "PATH" environment
       ' variable. If required your package can install
       ' JT.EXE to your program directory (as the CA's
       ' are run after files are installed) in which case
       ' you would specify the full path on the
       ' "WISEINST_SCHEDULE_JT_EXE_NAME" definition.
       ' Note that the program is only required for
       ' job installation, not for uninstall.
       '
       ' This code has VBscript error checking turned off
       ' in parts so that not only should it work as a
       ' custom action but it can be tested from a command
       ' line (you will need to add call to
       ' install/uninstall function).
       '************************************************<?NewLine>
    
       ;--- Define some variables -----------------------------------------------
       public rLog                               ;;Used for MSI logging
       public ScheduleName(<??ScheduleNumber>)   ;;Array to hold schedule name
       public ScheduleSpec(<??ScheduleNumber>)   ;;Array to hold schedule spec (switches/parameters for JT.EXE)
    
       ;--- Prepare for send of messages ----------------------------------------
       on error resume next
       set rLog = Installer.CreateRecord(1)
       Debug("")
       Debug("")
       Debug("Schedule Custom Action VBS")
    ;;;Debug("PRODUCT NAME: " & Session.Property("ProductName"))
    ;;;Debug("PRODUCT  VER: " & Session.Property("ProductVersion"))
       Debug("PRODUCT NAME: <$ProductName>")
       Debug("PRODUCT  VER: <$ProductVersion>")
       Debug("PRODUCT  MSI: <??MsiShortName>")
       Debug("")
       on error goto 0
    
       ;--- Work out where TASK folders is --------------------------------------
       public TasksDir
       set oShell   = CreateObject("WScript.Shell")
       set oProcEnv = oShell.Environment("PROCESS")
       TasksDir     = oProcEnv("SYSTEMROOT")
    
       ;--- Get File system object ----------------------------------------------
       public oFS : set oFS = CreateObject("Scripting.FileSystemObject")
    
    #)
    #( '<?NewLine>'
       ;--- Name Macro ----------------------------------------------------------
       #define SCHEDULE_VBSCRIPT_END
           <?NewLine>
           <?NewLine>
           <?NewLine>
    
           ;--- Some code which should be commented out when called as CA -------
           '$$$$$$$[ Uncomment for command line TESTING ONLY ]$$$$$$'
           'InstallSchedules()    'Remember that "<$WISEINST_SCHEDULE_JT_EXE_NAME>" must exist!
           'UnInstallSchedules()
           '$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$$'
           <?NewLine>
           <?NewLine>
    
           '============================================================================
           function InstallSchedules()            'Called by CA during install
           '============================================================================
               InstallSchedules = 0
               Debug("Installing " & ubound(ScheduleName) & " Schedule(s)")
               for ScheduleNumber = 0 to ubound(ScheduleName)-1
                   ;--- Delete the existing job file ----------------------------
                   DeleteSchedule(ScheduleNumber)
    
                   ;--- Work out the command line -------------------------------
                   JtCmd =         """<$WISEINST_SCHEDULE_JT_EXE_NAME>"" "
                   JtCmd = JtCmd & ScheduleSpec(ScheduleNumber) & " "
                   JtCmd = JtCmd & "/svj """ & GetJobFileName(ScheduleNumber) & """"
    
                   ;--- Execute the task ----------------------------------------
                   Debug("Installing schedule: " & ScheduleName(ScheduleNumber))
                   Debug "Executing"
                   Debug "~~~~~~~~~"
                   Debug JtCmd
                   JtExeRc = oShell.run(JtCmd, 0, true)
                   Debug "JT Rc = " & JtExeRc
                   Debug ""
                   if  JtExeRc <> 0 then
                       ;--- We will stop install --------------------------------
                       InstallSchedules = 1603      ''Stop Update
    
                       ;--- Display error ---------------------------------------
                       Title = "Failed Scheduling: " & ScheduleName(ScheduleNumber)
                       Text  = "Could not create the job using the command below "
                       Text  = Text & "(<$WISEINST_SCHEDULE_JT_EXE_NAME> returned a return code of " & JtExeRc & ")" & vbCrLf & vbCrLf
                       Text  = Text & JtCmd
                       Debug "------------------------------------------"
                       Debug Title
                       Debug Text
                       Debug "------------------------------------------"
                       msgbox Text, VbCritical, Title
                   end if
               next
               Debug("CA Return Code = " & InstallSchedules)
               Debug("")
           end function
    
           <?NewLine>
           '============================================================================
           function UnInstallSchedules()        'Called by CA during uninstall
           '============================================================================
               UnInstallSchedules = 0
               Debug("UnInstalling " & ubound(ScheduleName) & " Schedule(s)")
               for ScheduleNumber = 0 to ubound(ScheduleName)
                   ;--- Delete the existing job file ----------------------------
                   Debug("Removing schedule: " & ScheduleName(ScheduleNumber))
                   DeleteSchedule(ScheduleNumber)
               next
               Debug("CA Return Code = " & UnInstallSchedules)
               Debug("")
           end function
    
    
           <?NewLine>
           '============================================================================
           sub DeleteSchedule(JobNumb)
           '============================================================================
               JobFile = GetJobFileName(JobNumb)
               if  not oFS.FileExists(JobFile) then
                   Debug("Schedule does not exist: " & JobFile)
               else
                   Debug("Deleting Schedule: " & JobFile)
                   set fileobj = oFS.GetFile(JobFile)
                   fileobj.Delete
               end if
           end sub
    
    
           <?NewLine>
           '============================================================================
           function GetJobFileName(JobNumb)
           '============================================================================
               GetJobFileName = TasksDir & "\TASKS\" & ScheduleName(JobNumb) & ".job"
           end function
    
    
           <?NewLine>
           '============================================================================
           sub Debug(What)
           '============================================================================
               on error resume next
    
               ;--- WSCRIPT not available in CA ---------------------------------
               wscript.echo What
    
               ;--- Can't log message in MSI log out of CA! ---------------------
               dim VbBug: VbBug = What
               if VbBug <> "" then
                  VbBug = "    VBS-> " & VbBug
               end if
               rLog.StringData(0) = VbBug
               session.message &H04000000, rLog
           end sub
    #)
    #DefineRexx 'SCHEDULE_VBSCRIPT_MIDDLE'     ;;Generates arrays
       ;--- Fill VB arrays with information about the schedules -----------------
       Middle = ''
       do  SpecNum = 1 to ScheduleNumber
           ;--- Get info --------------------------------------------------------
           ThisName = ScheduleList_NAME.SpecNum
           ThisSpec = ScheduleList_SPEC.SpecNum
    
           ;--- Make safe within VB string --------------------------------------
           ThisName = ReplaceString(ThisName, '"', '""');
           ThisSpec = ReplaceString(ThisSpec, '"', '""');
    
           ;--- Now add to the VB code being generated --------------------------
           Middle = Middle || 'ScheduleName(' || SpecNum-1 || ') = "' || ThisName || '"<?Newline>'
           Middle = Middle || 'ScheduleSpec(' || SpecNum-1 || ') = "' || ThisSpec || '"<?Newline>'
       end
    #DefineRexx
    
    ;--- Define macro called at end of the package to create the CA code --------
    #( ''
       ;--- Name Macro ----------------------------------------------------------
       #define AddScheduleCustomAction
    
       ;--- Say what we are doing -----------------------------------------------
       <$HereWeAre "{$?MacName} - Generating VB and adding to MSI">
    
       ;--- Generate VBSCRIPT ---------------------------------------------------
       #if [ScheduleNumber <> 0]
           ;--- There was at least one schedule ---------------------------------
           #define SCHEDULE_KEY_BINARYTABLE JtScheduleVbs
           #define SCHEDULE_FILE            out\schedule.vbs
           #output "<$SCHEDULE_FILE>" ASIS OTHER
               <$SCHEDULE_VBSCRIPT_START>                   ;;Fixed VBS part - start
               <?NewLine>
               <?NewLine>
               #evaluate ^^ ^<$SCHEDULE_VBSCRIPT_MIDDLE>^   ;;Fill in schedule details
               <??Middle>
               <?NewLine>
               <$SCHEDULE_VBSCRIPT_END>                     ;;Fixed VBS part - end
               <?NewLine>
           #output
    
           ;--- Add the schedule VBS to the MSI ---------------------------------
           <$AddBinary KEY="<$SCHEDULE_KEY_BINARYTABLE>" file="<$SCHEDULE_FILE>">
    
           ;--- Define Install and uninstall Custom Actions ---------------------
           #define SCHEDULE_CA_INSTALL   SchedulesInstall_WISEINST
           #define SCHEDULE_CA_UNINSTALL SchedulesUnInstall_WISEINST
           <$TABLE "CustomAction">
                   ;--- Install -------------------------------------------------
                   <$Row                                                      \
                      Action="<$SCHEDULE_CA_INSTALL>"       ;;CA key          \
                        Type="<$WISEINST_SCHEDULE_CA_TYPE>" ;;Run VBS         \
                      Target="InstallSchedules"             ;;VBS Entry point \
                      Source="<$SCHEDULE_KEY_BINARYTABLE>"                    \
                   >
    
                   ;--- Uninstall -----------------------------------------------
                   <$Row                                                        \
                      Action="<$SCHEDULE_CA_UNINSTALL>"      ;;CA key           \
                        Type="<$WISEINST_SCHEDULE_CA_TYPE>"  ;;Run VBS          \
                      Target="UnInstallSchedules"            ;;VBS Entry point  \
                      Source="<$SCHEDULE_KEY_BINARYTABLE>"                      \
                   >
           <$/TABLE>
    
           ;--- Call schedule custom actions at appropriate times ---------------
           <$TABLE "InstallExecuteSequence">
                   ;--- Install -------------------------------------------------
                   <$Row                                                  \
                         Action="<$SCHEDULE_CA_INSTALL>"                  \
                      Condition="<$WISEINST_SCHEDULE_INSTALL_CA_COND>"    \
                       Sequence="<$WISEINST_SCHEDULE_INSTALL_CA_WHEN>"    \
                   >
    
                   ;--- Uninstall -----------------------------------------------
                   <$Row                                                  \
                         Action="<$SCHEDULE_CA_UNINSTALL>"                \
                      Condition='<$WISEINST_SCHEDULE_UNINSTALL_CA_COND>'  \
                       Sequence="<$WISEINST_SCHEDULE_UNINSTALL_CA_WHEN>"  \
                   >
           <$/TABLE>
    
           ;--- Make sure Progress Bar is updated when CAs are run --------------
           <$TABLE "ActionText">
                   <$Row                                         \
                           Action="<$SCHEDULE_CA_INSTALL>"       \
                      Description="Installing <??ScheduleNumber> task schedules"
                   >
                   <$Row                                         \
                           Action="<$SCHEDULE_CA_UNINSTALL>"     \
                      Description="Removing <??ScheduleNumber> task schedules"
                   >
           <$/TABLE>
    
           ;--- Make sure we don't do this twice! -------------------------------
           #RexxVar ScheduleNumber = 0
       #endif
    #)
    
    
    
    ;--- Load Icon File into a VB Variable (fails or returns VBCODE in 'VbCode') -
    #NextId
    #DefineRexx 'LoadIconIntoVbVariable' NOPACK
            ;--- An Icon file should be small (and separate from pgm)! ----------
            #define? ICON_MAX_SIZE  20000          ;;Default max size
            @@IconFile = '{$#1}';
            @@IconSize = stream(@@IconFile, 'c', 'query size');
            if @@IconSize = '' then
               error('The icon "' || @@IconFile || '" could not be found.');
            if @@IconSize > <$ICON_MAX_SIZE> then
               error('The icon "' || @@IconFile || '" is ' || AddCommasToDecimalNumber(@@IconSize) || ' bytes long', 'An icon file must be SMALL (currently defined to be <= ' || AddCommasToDecimalNumber(<$ICON_MAX_SIZE>) || ' bytes).');
    
            ;--- Read the icon's data into memory -------------------------------
            @@CloseRc      = stream(@@IconFile, 'c', 'close');
            @@IconContents = charin(@@IconFile, 1, 99999);
            @@CloseRc      = stream(@@IconFile, 'c', 'close');
            if length(@@IconContents) <> @@IconSize then
               error('Could not successfully read the icon "' || @@IconFile || '".');
    
            ;--- Create a VB variable containing the data -----------------------
            <$MakeDataSafeInVbLiteral VBVAR="ID" RXVAR="@@IconContents">
    #DefineRexx
    
    ;--- Create a VB variable containing the data (returns code in "VbCode") ----
    #NextId
    #DefineRexx 'MakeDataSafeInVbLiteral' NOPACK
           ;--- Get parameters --------------------------------------------------
           @@Data  = {$RxVar}               ;;Get data into known variable
           @@VbVar = '{$VbVar}'             ;;Get VBVAR name
    
           ;--- Break into multiple lines ---------------------------------------
           #define? MAX_DATA_BLOCK  30
           #define? MAX_DATA_BLOCK  100
           VbCode = @@VbVar || ' = ""<?NewLine>'
           do  while @@Data \== ''
               ;--- How big a chunk should we process? --------------------------
               @@Grab = length(@@Data)
               if  @@Grab > <$MAX_DATA_BLOCK> then
                   @@Grab = <$MAX_DATA_BLOCK>;
    
               ;--- Grab the chunk ----------------------------------------------
               @@Chunk = left(@@Data, @@Grab);
               @@Data  = substr(@@Data, @@Grab+1);
    
               ;--- Now Make sure that all characters are OK --------------------
               @@PreFix = '" & ';
               @@Suffix = ' & "';
               @@Chunk = ReplaceString(@@Chunk, '"',     @@PreFix || 'chr(' || c2d('"') || ')' || @@Suffix);
               @@Chunk = ReplaceString(@@Chunk, '0D0A'x, @@PreFix || 'vbCRLF' || @@Suffix);
               @@Chunk = ReplaceString(@@Chunk, '0D'x,   @@PreFix || 'vbCR'   || @@Suffix);
               @@Chunk = ReplaceString(@@Chunk, '0A'x,   @@PreFix || 'vbLF'   || @@Suffix);
               do @@Chr = 0 to 31
                  @@Chunk = ReplaceString(@@Chunk, d2c(@@Chr), @@PreFix || 'chr(' || @@Chr || ')' || @@Suffix);
               end;
               do @@Chr = 128 to 255
                  @@Chunk = ReplaceString(@@Chunk, d2c(@@Chr), @@PreFix || 'chr(' || @@Chr || ')' || @@Suffix);
               end;
    
               ;--- Quote the value ---------------------------------------------
               @@Chunk = '"' || @@Chunk || '"'
    
               ;--- Need to remove '""' stuff from start and end ----------------
               @@LookS = '"" & '
               @@LookE = ' & ""'
               if  left(@@Chunk, length(@@LookS)) == @@LookS then
                   @@Chunk = substr(@@Chunk, length(@@LookS)+1)
               if  right(@@Chunk, length(@@LookE)) == @@LookE then
                   @@Chunk = left(@@Chunk, length(@@Chunk)-length(@@LookE))
    
               ;--- "Reduce" the VB command as far as possible ------------------
               @@Chunk = ReplaceString(@@Chunk, '& "" &', '&')
    
               ;--- Create new VB command to append to existing data ------------
               VbCode = VbCode || @@VbVar || ' = ' || @@VbVar || ' & ' || @@Chunk || '<?NewLine>'
           end;
    #DefineRexx
    
    
    ;--- Used by any header files to mark version like info ---------------------
    #define    RecordDetailsAboutThisHeaderFile                               \
               #evaluate ^^ ^<$Rexx4RecordDetailsAboutThisHeaderFile {$?}>^  -\
               <??Generating>
    #DefineRexx 'Rexx4RecordDetailsAboutThisHeaderFile'
               ;--- Work out the property name ----------------------------------
               if '{$FileName=^^}' = '' then
               do
                   ;--- Use the "CURRENT" input files name (normal use) ---------
                   HeaderFile = InputComponentLevel();
               end;
               else
               do
                   ;--- User wants SPECIFIC file details added ------------------
                   HeaderFile = '{$FileName}';
               end;
               HeaderId = '<$WISEINST_PROP_PREFIX>Header_' || _filespec('name', HeaderFile);
    
               ;--- Get some identifying characteristics (name, version, size and timestamp) ---
               HeaderSize = AddCommasToDecimalNumber(stream(HeaderFile, 'c', 'query size'));
               <$Rexx2GetFormattedFileTime FileVar="HeaderFile" TIMEVAR="Time" DATEVAR="Date">
               HeaderTime  = Date || ' at ' || Time
               HeaderValue = HeaderFile || ' (v{$Version}, ' || HeaderSize || ' bytes, dated ' || HeaderTime || ')'
    
               ;--- Generate code to create the property ------------------------
               Generating = '<' || '$SetProperty NAME="' || HeaderId || '"  VALUE=^' || HeaderValue || '^><?NewLine>' || d2c(10)
    #DefineRexx
    
    
    ;----------------------------------------------------------------------------
    ;--- Convert File time stamp into nicely formatted date/time ----------------
    ;----------------------------------------------------------------------------
    #NextId
    #DefineRexx 'Rexx2GetFormattedFileTime'
       ;--- Can either be passed a timestamp or a file name ---------------------
       @@FileTs = {$TSVAR=^""^};
       if  @@FileTs = '' then
       do
           ;--- A timestamp was not passed --------------------------------------
           @@FileTs = GetFileTimeStamp({$FileVar='ShouldNotDefaultHere...'});
           if  @@FileTs = -1 then
               error('Could not get the time for the file "' || {$FileVar} || '".');
       end;
    
       ;--- Convert date --------------------------------------------------------
       @@Spc  = '{$DATESPC=^ ^}';
       @@DD   = substr(@@FileTs, 7, 2);
       @@MM   = substr(@@FileTs, 5, 2);
       @@YYYY = left(@@FileTs, 4);
       {$DATEVAR} = @@DD+0 || @@Spc || word('Jan Feb Mar Apr May Jun Jul Aug Sep Oct Nov Dec', @@MM) || @@Spc || @@YYYY
    
       ;--- Convert time --------------------------------------------------------
       {$TIMEVAR} = GetAmPmTimeFromHhMmSs(substr(@@FileTs, 9));
    #DefineRexx
    
    
    ;----------------------------------------------------------------------------
    ;--- Generic Counter --------------------------------------------------------
    ;----------------------------------------------------------------------------
    #NextId
    #define      WiCounter                        \
                 <$Rexx4WiCounter {$?} $$RXEXEC>
    #DefineRexx  'Rexx4WiCounter'
       @@CntVAR    = 'WICOUNTER_' || c2x(translate('{$#1}'));  ;;Generate Rexx var name unlikely to clash with anything!
       @@NumDigits = '{$Digits=^3^}'                           ;;By default padded to 3 digits
       if  symbol(@@CntVAR) <> 'VAR' then                      ;;Get incremented value
           @@Val = 1;
       else
           @@Val = value(@@CntVAR) + 1;
       call value @@CntVAR, @@Val;                ;;Remember value
    
       ;--- Pad the value (NEVER truncate!). Padding allows sorting in Orca etc -
       if  length(@@Val) >= @@NumDigits then
           RxExec = @@Val;                          ;;Don't pad!
       else
           RxExec = right(@@Val, @@NumDigits, '0'); ;;Pad to left with zeros
    #DefineRexx
    
    
    ;----------------------------------------------------------------------------
    ;--- Get full name of file given possibly shortname (must exist) ------------
    ;----------------------------------------------------------------------------
    #DefineRexx 'GetFullFileName'          ;;Handy from an otherwise non-rexx macro
       call Debug 'Macro: GetFullFileName for "{$FileName}"'
       call DebugIndent 1;
       {$FullVar} = stream('{$FileName}', 'c', 'query exists')
       if  {$FullVar} = '' then
           error('The {$Item=^file^} "{$FileName}" could not be found!')
       call Debug 'Full name: ' || {$FullVar}
       call Debug 'Dated    : ' || stream({$FullVar}, 'c', 'query datetime')
       call Debug 'Size     : ' || stream({$FullVar}, 'c', 'query size')
       call DebugIndent -1;
    #DefineRexx
    
    ;----------------------------------------------------------------------------
    ;--- The following Code should be at START of generated code ----------------
    ;----------------------------------------------------------------------------
    #( '<?NewLine>'
       ;--- Define name of macro ------------------------------------------------
       #define VBSCRIPT_AT_START
    
               '----------------------------------------------------------------
               ' This file was automatically produced by PPWIZARD.
               '
               ' PPWIZARD is a FREE product (for private or commercial use),
               ' available from:
               '
               '      <?PpwizardHomePage>
               '
               ' Apart from possiblity doing some debugging do not modify this
               ' file as your changes will get lost when the file is
               ' regenerated.
               '
               '
               ' DETAILS
               ' ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
               ' Generated VB: <?OutputFile>
               ' From        : <?InputFile>
               ' At          : <?CompileTime>
               ' PPWIZARD    : v<?Version> of <?PpwizardPgm>
               ' Header      : v<$WISEINST_VERSION> of <$WISEINST_HEADER>
               '----------------------------------------------------------------
    
               ;--- Require all used variables to be defined --------------------
               <?NewLine>
               Option Explicit
    
               ;--- Define some global variables --------------------------------
               dim <$WiseObj>
               dim TableEnvironment           ;;Used by PATH   macro
               dim IconTable, IconRow         ;;Used by ADDICON macro
               dim RegistryTable              ;;Used by AddRegistry macro
               dim RegistryRows, RegistryRow
               dim ShortCutTable              ;;Used by ADDSHORTCUT macro
               dim ShortCutRows, ShortCutRow
               dim CurrentTable                    ;;Used by TABLE macros
               dim CurrentRows, CurrentRow, BinCol ;;Used by ROW   macros
               dim BinaryKey(<$WISEINST_MAX_BINARY_ENTRIES>)
               dim BinaryFile(<$WISEINST_MAX_BINARY_ENTRIES>)
               dim ID                         ;;Used to Hold binary data of icon
               dim TmpText1, TmpText2         ;;Some temporary text strings
               dim TmpText3, TmpText4         ;;Some temporary text strings
               dim StartTime      : StartTime        = timer()
               dim HereWeAreLoc   : HereWeAreLoc     = "(?)"
               dim HereWeAreLocTxt: HereWeAreLocTxt  = "Beginning"
               dim Row
               dim PvComponent
               dim KeyPath, Key, Ok
               dim NL, NP
               NL = chr(10) & chr(13)
               NP = NL & NL
    
               ;--- Set up some VB runtime "constants" (I support user access to these) ---
               dim VbMadeTime          ;;Date/Time VbScript was run to produce the package
               VbMadeTime = FormatDateTime(date(), vbLongDate) & " " & time()
    
               ;--- Call mainline() ---------------------------------------------
               #if ['<$RUNTIME_TRAPS_DETECTED>' = 'N']
                   ;--- Execute code (never returns) ----------------------------
                   #ifdef DEBUG_OUTPUT
                       Say  "As Per your request there was no trap handler added!"
                   #endif
                   MainLine()
               #elseif
                   ;--- Define error handler ------------------------------------
                   on error resume next
    
                   ;--- Execute code (never returns) ----------------------------
                   MainLine()
    
                   ;--- If we get here we had a runtime error (display the error) ---
                   Say ""
                   Say "VBSCRIPT TRAP Detected"
                   Say "~~~~~~~~~~~~~~~~~~~~~~"
                   Say "Error Number: " & CStr(Err.Number)
                   Say "Desc        : " & Err.Description
                   Say "Near        : " & HereWeAreLocTxt
                   Say "In Script   : " & WScript.ScriptFullName
                   Say "Detected by : " & Err.Source
    
                   ;--- Do we want a message box as well? -----------------------
                   #ifndef NO_POPUP_ON_TRAP
                           dim Text, Title
                           Title = "TRAP IN " & WScript.ScriptName
                           Text  = "Error # " & CStr(Err.Number) & " " & Err.Description & NP & "Error occurred near " & HereWeAreLocTxt
                           MsgBox Text, vbCritical, Title
                   #endif
    
                   ;--- Attempt to save WSI for possible debugging --------------
                   Say ""
                   Say "Saving WSI for debugging..."
                   Ok = <$WiseObj>.Save("<$GENERATE_WSI>")
               #endif
    
               ;--- Trap EXIT ---------------------------------------------------
               Wscript.Quit 218
    
               ;--- Define start of Mainline ------------------------------------
               <?NewLine>
               <?NewLine>
               '============================================================================
               Sub MainLine
               '============================================================================
    
               ;--- Show user what is being built -------------------------------
               Say "We are building ""<$GENERATE>"""
    
               ;--- Delete WSI/MSI (proves not in use etc) ----------------------
               <$HereWeAre "Deleting Files">
               DeleteFile "<$GENERATE_WSI>"
               DeleteFile "<$GENERATE_MSI>"
    
               ;--- Connect to Wise for Windows Installer object ----------------
               <?NewLine>
               <$HereWeAre "{$?MacName}">
               Say "Creating Wise Document"
               Set <$WiseObj> = Nothing
               Set <$WiseObj> = Wscript.CreateObject("WfWi.Document")
    
               ;--- Make sure exceptions are turned on --------------------------
               <$HereWeAre "{$?MacName} - Making sure Exceptions are enabled">
               <$WiseObj>.EnableExceptions(TRUE)
    
               ;--- Want to see SAVING/GENERATING Popups (default is YES)? ------
               #ifdef NO_WISE_PROGRESS_POPUPS
                      <$HereWeAre "{$?MacName} - Disabling Saving/Generating progress popups">
                      <$WiseObj>.SetSilent()
               #endif
    
               ;--- Make MSI ----------------------------------------------------
               #define NEWT_INSTALLER_DB_PROJECT 1
               #define NEWT_MERGE_MODULE_PROJECT 3
               Ok = <$WiseObj>.NewEx({$TYPE="<$NEWT_INSTALLER_DB_PROJECT>"}, {$WANTPRJFILE="TRUE"})
               <$DieIfNotOk>
    
               ;--- Set a GENERATOR property ("Creating Application" summary does not work?) ---
               #define? WISEINST_GENERATOR_TEXT  PPWIZARD v<?Version> (FreeWare, see <?PpwizardHomePage>)
               <$SetProperty NAME="<$WISEINST_PROP_PREFIX>Generator"  VALUE=^<$WISEINST_GENERATOR_TEXT>^>
    
               ;--- Record details about THIS header file -----------------------
               <$RecordDetailsAboutThisHeaderFile VERSION=^<$WISEINST_VERSION>^ FILENAME=^<??WiseInstHeaderFile>^>
    
               ;--- Space out ---------------------------------------------------
               <?NewLine>
               <?NewLine>
               {$!}
    #)
    
    
    ;----------------------------------------------------------------------------
    ;--- The following Code should be at END of generated code ------------------
    ;----------------------------------------------------------------------------
    #( '<?NewLine>'
       ;--- Define name of macro ------------------------------------------------
       #define VBSCRIPT_AT_END
    
               ;--- Now save the WSI file (if case compile saves can look at WSI) ---
               <?NewLine>
               <$HereWeAre "{$?MacName} - Generating Files">
               Say "Generating: <$GENERATE_WSI>"
               Ok = <$WiseObj>.Save("<$GENERATE_WSI>")
               <$DieIfNotOk>
    
               ;--- Handy Debug Hook --------------------------------------------
               #define? DEBUG_HOOK_AFTER_SAVE
               <$DEBUG_HOOK_AFTER_SAVE>
    
               ;--- Generate the MSI file ---------------------------------------
               Say "Compiling: <$GENERATE_WSI>"
               Ok = <$WiseObj>.Compile("<$GENERATE_WSI>")
               <$DieIfNotOk>
    
               ;--- Double check files exist (Wise won't complain on error!) ----
               <$HereWeAre "Double checking files were generated">
               FileMustExist "<$GENERATE_WSI>"
               FileMustExist "<$GENERATE_MSI>"
    
               ;--- Handy Debug Hook --------------------------------------------
               #define? DEBUG_HOOK_AFTER_COMPILE
               <$DEBUG_HOOK_AFTER_COMPILE>
    
               ;--- Release resources -------------------------------------------
               <$HereWeAre "Releasing resources">
               set <$WiseObj> = Nothing
    
               ;--- If we have any binary resources to add then do so -----------
               #if [RxBinaryCnt <> 0]
                    HereWeAre "", "Adding <??RxBinaryCnt> binary resources to WSI"
                    AddBinaryResources("<$GENERATE_WSI>")
                    HereWeAre "", "Adding <??RxBinaryCnt> binary resources to MSI"
                    AddBinaryResources("<$GENERATE_MSI>")
               #endif
    
               ;--- Add any icons -----------------------------------------------
               #if  AddIconCnt <> 0
                    HereWeAre "", "Hacking icons into WSI (Wise 3.1 workaround)....."
                    #evaluate ^^ ^<$UpdateMsiForIcons FILE="<$GENERATE_WSI>">^
                    <??VbCode>
                    HereWeAre "", "Hacking icons into MSI (Wise 3.1 workaround)....."
                    #evaluate ^^ ^<$UpdateMsiForIcons FILE="<$GENERATE_MSI>">^
                    <??VbCode>
                    HereWeAre "", "Hacking complete!"
               #endif
    
               ;--- Thats All Folks! --------------------------------------------
               dim Elapsed: Elapsed = timer() - StartTime
               if Elapsed < 0 then
                   Elapsed = Elapsed + (60*60*24)
               end if
               Elapsed = round(Elapsed, 0)
               Say "Thats All Folks!!! Product was successfully packaged (took " & Elapsed & " seconds)."
               Wscript.Quit 0{$!}
    
               ;--- Define end of Mainline() ------------------------------------
               End Sub 'Mainline
    
               ;--- We are about to die because of an invalid return code -------
               <?NewLine>
               <?NewLine>
               <?NewLine>
               '============================================================================
               Sub Die(Why)
               '============================================================================
                   ;--- Output a header -----------------------------------------
                   Say ""
                   Say "Error Detected"
                   Say "~~~~~~~~~~~~~~"
    
                   ;--- Output the WISE return code -----------------------------
                   Say "Near    : " + HereWeAreLocTxt
                   if  Why = Null then
                       say "Wise Rc : " & <$WiseObj>.GetLastError()
                   else
                       say "Reason  : " & Why
                   end if
    
                   ;--- Display a popup unless user doesn't want one ------------
                   #ifndef NO_POPUP_ON_ERROR
                       dim Text, Title
                       Title = "ERROR IN " & WScript.ScriptName
                       if  Why = Null then
                           Text  = "Wise reports: " & <$WiseObj>.GetLastError()
                       else
                           Text =  "Reason: " & Why
                       end if
                       Text = Text & NP & "Error occurred near " & HereWeAreLocTxt
                       MsgBox Text, vbCritical, Title
                   #endif
    
                   ;--- Simply exit ---------------------------------------------
                   Wscript.Quit 219
               end sub
    
               ;--- Display a line ----------------------------------------------
               <?NewLine>
               '============================================================================
               Sub Say(What)
               '============================================================================
                   Wscript.Echo What
               end sub
    
               ;--- Display a line ----------------------------------------------
               <?NewLine>
               '============================================================================
               Sub HereWeAre(Loc, Txt)
               '============================================================================
                   ;--- Remember where we are -----------------------------------
                   if  Loc <> "" then
                       HereWeAreLoc = Loc
                   end if
                   HereWeAreLocTxt = HereWeAreLoc + " " + Txt
    
                   ;--- If in debug mode we display the text --------------------
                   #if ['<$VERBOSE_OUTPUT>' = 'Y']
                       Wscript.Echo HereWeAreLocTxt
                   #endif
               end sub
    
               ;--- File MUST Exist ---------------------------------------------
               <?NewLine>
               '============================================================================
               Sub FileMustExist(FileName)
               '============================================================================
                   dim fso
                   set fso = CreateObject("Scripting.FileSystemObject")
                   if  not fso.FileExists(FileName) then
                       Die("The file '" & FileName & "' does not exist!")
                   end if
               End Sub
    
               ;--- Delete a file -----------------------------------------------
               <?NewLine>
               '============================================================================
               Sub DeleteFile(FileName)
               '============================================================================
                   dim fso
                   set fso = CreateObject("Scripting.FileSystemObject")
                   if  fso.FileExists(FileName) then
                       ;--- Delete it -------------------------------------------
                       dim Reason
                       on error resume next
                       fso.DeleteFile(FileName)
                       Reason = Err.Description
    
                       ;--- Ensure it has been deleted --------------------------
                       if  fso.FileExists(FileName) then
                           Die("Could not delete '" & FileName & "' (" & Reason & ")")
                       end if
                   end if
               End Sub
    
               ;--- Used to Check for Table/Key existance as well as returning Object ---
               <?NewLine>
               '============================================================================
               function GetTableRow(TableName, RowKey)
               ;
               ; Parms:
               ;
               ;  1. Table Name. If "" then it is assumed we are within a
               ;     $Table macro block
               ;
               ;  2. The key of the row being queried
               ;
               ; Example of use:
               ;
               ;   set Obj = GetTableRow("Control", "Admin_Install_Point,Text54")
               ;   if Obj Is Nothing then
               ;      '--- Table or  specified key does not exist ---
               ;   else
               ;      '--- Update the row ---------------------------
               ;       Obj("X")    = 999
               ;       Obj("Text") = "999...."
               ;       set Obj = Nothing
               ;   end if
               '============================================================================
                   ;--- Define some variables -----------------------------------
                   dim RowTable, RowCollection
    
                   ;--- If can't get data return NULL ---------------------------
                   set GetTableRow = Nothing
                   on error resume next
    
                   ;--- Do we need to work out the table? -----------------------
                   if  TableName = "" then
                       set RowCollection  = CurrentRows    ;;Set up by $Table macro
                   else
                       ;--- Get access to table -------------------------------------
                       set RowTable = <$WiseObj>.WTables(TableName)
                       if  Err.Number <> 0 then
                           exit function
                       end if
    
                       ;--- Get access to rows collection ---------------------------
                       set RowCollection  = RowTable.WRows()
                       if  Err.Number <> 0 then
                           exit function
                       end if
                   end if
    
                   ;--- Use the key to access the row ---------------------------
                   set GetTableRow = RowCollection.Row(RowKey)
    
                   ;--- Thats all Folks! Clean up a bit -------------------------
                   set RowTable       = Nothing
                   set RowCollection  = Nothing
               end function
    
               ;--- Makes sure we have "short|long" file spec -------------------
               <?NewLine>
               '============================================================================
               function ShortLongSpec(PassedSpec)
               '============================================================================
                   ;--- May already have the shortname attached -----------------
                   if  instr(1, PassedSpec, "|", 1) <> 0 then
                       ;--- Already contains short and long specs ---------------
                       ShortLongSpec = PassedSpec
                   else
                       ShortLongSpec = GuessFatFileName(PassedSpec) & "|" & PassedSpec
                   end if
               end function
    
    
               ;--- Creates a SHORT filename from a LONG one (user can replace) -
               <?NewLine>
               #ifndef WISEINST_REPLACED_GuessFatFileName        ;;Allow user to replace
               '============================================================================
               function GuessFatFileName(WholeLongName)
               ;
               ; Given a long filename (with or without path components) will
               ; return a FAT filename (~1's etc).
               ;
               ; Note that Thanks to Bill it is not actually possible to
               ; determine the short name for a non-existant file but here we
               ; make a reasonable guess. It should be noted that it is a guess
               ; and it is impossible to do better. As with a lot of things
               ; Windows, results will depend of your luck.
               '============================================================================
                   ;--- Define variable that user should put result in ----------
                   dim ShortNames, I
                   dim Pos, FileName, FileExtn
    
                   ;--- Split into directory components -------------------------
                   ShortNames = split(WholeLongName, "\")
    
                   ;--- Process each bit ----------------------------------------
                   for I = 0 to ubound(ShortNames)
                       ;--- Take case of invalid shortname characters -----------
                       FileName = ShortNames(I)
                       FileName = replace(FileName, " ", "")
    
                       ;--- Seperate file and extension -------------------------
                       Pos = instrrev(FileName, ".")  ;;Look for last "."
                       if  Pos = 0 then
                           ;--- No Extension ------------------------------------
                           FileExtn = ""
                       else
                           ;--- Has an extension --------------------------------
                           FileExtn = mid(FileName, Pos, 4)   ;;Extn includes the dot (only was first 3 chars of long extn)
                           FileName = left(FileName, Pos-1)
                       end if
    
                       ;--- Now Look at the filename and see if we need "~1" ----
                       if  len(FileName) > 8 then
                           FileName = left(FileName, 6) & "~1"
                       end if
    
                       ;--- Recombine -------------------------------------------
                       ShortNames(I) = FileName & FileExtn
                   next
    
                   ;--- Return the short name value -----------------------------
                   GuessFatFileName = join(ShortNames, "\")
               end function
               #endif
    
               ;--- Checks "KEY" return codes -----------------------------------
               <?NewLine>
               Sub KeyMustBeOk(ThisMustBeNonBlank)
                   if  ThisMustBeNonBlank = "" then
                       Die(Null)
                   end if
               end sub
    
               ;--- Checks Boolean return codes ---------------------------------
               <?NewLine>
               Sub BoolMustBeTrue(ThisMustBeTrue)
                   if  not ThisMustBeTrue  then
                       Die(Null)
                   end if
               end sub
    
    
               ;--- Add Binary fields "Binary Table" ----------------------------
               <?NewLine>
               <?NewLine>
               '============================================================================
               sub AddBinaryResources(MsiFile)
               '============================================================================
                   ;--- Open Windows Installer object ---------------------------
                   dim Installer
                   set Installer = Wscript.CreateObject("WindowsInstaller.Installer")
    
                   ;--- Open an MSI database (file) in READ/WRITE mode ----------
                   dim MsiDb
                   set MsiDb = Installer.OpenDatabase(MsiFile, 2)  'Open Read/Write No Transactions
    
                   ;--- Open BINARY table ---------------------------------------
                   dim View, Record
                   set View = MsiDb.OpenView("SELECT Name,Data FROM Binary")
                   View.Execute
    
                   ;--- Add All binaries to table -------------------------------
                   dim BinIndex
                   for BinIndex = 1 to <??RxBinaryCnt>
                       ;--- Create a record (with 2 fields) ---------------------
                       set Record = Installer.CreateRecord(2)
    
                       ;--- Update the fields -----------------------------------
                       Record.StringData(1) = BinaryKey(BinIndex)
                       Record.SetStream 2,    BinaryFile(BinIndex)
    
                       ;--- Insert the record -----------------------------------
                       View.Modify 1, Record
                       set Record = Nothing
                   next
    
                   ;--- Need to call "commit" to write data ---------------------
                   MsiDb.commit()
               end sub
    
               ;--- Add ICONs to "Icon Table" -----------------------------------
               <?NewLine>
               <?NewLine>
               '============================================================================
               Sub HackIconIntoMsi(IconKey, IconFile, MsiFile)
               '============================================================================
                   ;--- Open Windows Installer object ---------------------------
                   dim Installer
                   set Installer = Wscript.CreateObject("WindowsInstaller.Installer")
    
                   ;--- Open an MSI database (file) in READ/WRITE mode ----------
                   dim MsiDb
                   set MsiDb = Installer.OpenDatabase(MsiFile, 2)  'Open Read/Write No Transactions
    
                   ;--- Open ICON table -----------------------------------------
                   dim View, Record, TableName
                   set View = MsiDb.OpenView("SELECT Name,Data FROM Icon")
                   View.Execute
    
                   ;--- Create a record -----------------------------------------
                   set Record = Installer.CreateRecord(2)
    
                   ;--- Update the fields ---------------------------------------
                   Record.StringData(1) = IconKey
                   Record.SetStream 2, IconFile
    
                   ;--- Insert the record ---------------------------------------
                   View.Modify 1, Record
    
                   ;--- Need to call "commit" to write data ---------------------
                   MsiDb.commit()
               end sub
    #)
    
    
    
    
    
    ;----------------------------------------------------------------------------
    ;--- Generates any HTML reports ---------------------------------------------
    ;----------------------------------------------------------------------------
    #NextId
    #(
       #define WISEINST_HTMLRPT_HAVE_PRETTY_DIR_WITHOUT_MAPPED
            '<span title="This is the key into the MSI directory table.
                          This can be useful when debugging.">'
            || '<font color=green>'
            || '<i>'
            ||     @@DstDirAlias
            || '</i>'
            || '</font>'
            || '</span>'
    #)
    #(
       #define WISEINST_HTMLRPT_HAVE_PRETTY_DIR_WITH_MAPPED
            <$WISEINST_HTMLRPT_HAVE_PRETTY_DIR_WITHOUT_MAPPED>
            || '<hr size=1>'
            || '<span title="This is the user friendly directory after
                             mapping.
                             This is only displayed when a mapping has
                             occurred.
                             &#13;&#10;&#13;&#10;It is displayed as
                             visual proof that a file was
                             or was not mapped.
                             This can be useful when debugging.">'
            || '<font color=olive>'
            || '<i>'
            ||      @@DstDirPrettyM
            || '</i>'
            || '</font>'
    #)
    #define WISEINST_HTMLRPT_PRETTY_PLUS_ALIAS \
            @@DstAliasPlusMapped || '<hr size=1>' || @@DstDirPretty
    #DefineRexx SetupHtmlRptVariables
       ;--- Split stored string back into into components -----------------------
       parse var RptFile.@@Index @@SortKey '0000'x @@Short '00'x @@DstDir '00'x @@SrcDir '00'x @@DateTs '00'x @@Size;
    
       ;--- See if we know the destination as a "user friendly" directory -------
       parse var @@DstDir '[' @@DirName ']'
       @@Key = 'WIDIR2UDIR_' || c2x(translate(@@DirName));
       if  symbol(@@Key) <> 'VAR' then
       do
           ;--- Don't know a user friendly name ---------------------------------
           @@DstDirP                = @@DstDir
           @@DstDirPretty           = BreakAt("20-30", @@DstDirP,  '_\ ');
           @@DstDirPrettyWithAlias  = @@DstDirPretty;
           @@DstAliasPlusMapped     = @@DstDirPretty;
       end;
       else
       do
           ;--- We know a friendly name -----------------------------------------
           @@DstDirP       = value(@@Key)
           @@DstDirPretty  = @@DstDirP;    ;;Looks nice and friendly :-)
           @@DstDirPretty  = BreakAt("20-30", @@DstDirPretty,  '_\ ');
    
           ;--- Want to add the alias (do first time) ---------------------------
           @@Key = 'HTMLRPT_AD_' || c2x(@@DstDir)
           if  symbol(@@Key) = 'VAR' then
               @@DstDirPrettyWithAlias = @@DstDirPretty;
           else
           do
               ;--- Don't do the following again! -------------------------------
               call value @@Key, '';
    
               ;--- Make the alias pretty ---------------------------------------
               @@DstDirAlias = BreakAt("20-30", @@DstDir,  '_\ ');
    
               ;--- We will also know a "pretty but mapped" name ----------------
               @@Key = 'WIDIR2UDIR_MAPPED_' || c2x(translate(@@DirName));
               @@DstDirPM      = value(@@Key)
               @@DstDirPrettyM = @@DstDirPM;    ;;Looks nice and friendly :-)
               @@DstDirPrettyM = BreakAt("20-30", @@DstDirPrettyM,  '_\ ');
    
               ;--- Combine Mapped + non mapped -------------------------------------
               if  @@DstDirPM = @@DstDirP then
                   @@DstAliasPlusMapped = <$WISEINST_HTMLRPT_HAVE_PRETTY_DIR_WITHOUT_MAPPED>;
               else
                   @@DstAliasPlusMapped = <$WISEINST_HTMLRPT_HAVE_PRETTY_DIR_WITH_MAPPED>
    
               ;--- This is the first time --------------------------------------
               @@DstDirPrettyWithAlias = <$WISEINST_HTMLRPT_PRETTY_PLUS_ALIAS>;
           end;
       end
    
       ;--- Get any comment the user has set up for the file --------------------
       <$Rexx4GetFileComment CmtVar=~@@FileCmt~ FileVar=~@@Short~ DestDirVarK=~@@DstDir~ DestDirVarP=~@@DstDirP~ SrcDirVar=~@@SrcDir~>
    
       ;--- Format the time of the file -----------------------------------------
       <$Rexx2GetFormattedFileTime TSVAR="@@DateTs" TIMEVAR="@@Time" DATEVAR="@@Date" DATESPC="&nbsp;">
    
       ;--- Make sure the columns are not too wide! -----------------------------
       @@Short   = BreakAt("20-30", @@Short,   '_ ');
       @@SrcDir  = BreakAt("30-40", @@SrcDir,  '\ ');
       @@DstDir  = BreakAt("20-30", @@DstDir,  '_\ ');
    #DefineRexx
    #define GenerateAnyHtmlReports                                              \
            ;--- Create start of Report file -----------------------------     -\
            #output "<$GENERATE_RPT>" ASIS HTML                                -\
            <$WISEINST_HTMLRPT_START>                                          -\
                                                                               -\
            ;--- Generate FILES report -----------------------------------     -\
            #if [RptFileCnt = 0]                                               -\
                <$WISEINST_HTMLRPT_NO_FILES>                                   -\
            #elseif                                                            -\
               ;--- Start the HTML table ---------------------------------     -\
               <$WISEINST_HTMLRPT_HEADING TEXT="FILES">                        -\
               <$WISEINST_HTMLRPT_FILETABLE_START>                             -\
                                                                               -\
               ;--- Sort file table entries ------------------------------     -\
               #evaluate ^^ ^call SortArray 'RptFile'^                         -\
               #ifdef WISEINST_HTMLRPT_REVERSE_FILE_ORDER                      -\
                   #evaluate ^^ ^call ReverseArray 'RptFile'^                  -\
               #endif                                                          -\
                                                                               -\
               ;--- Generate guts of report ------------------------------     -\
               #RexxVar @@Index = 1                                            -\
               #{                                                              -\
                   ;--- Split off components -----------------------------     -\
                   #evaluate ^^ ^<$SetupHtmlRptVariables>^                     -\
                                                                               -\
                   ;--- Generate the HTML for this file ------------------     -\
                   #evaluate ^^ ^<$WISEINST_HTMLRPT_FILETABLE_ROW>^            -\
                   <??H><?NewLine>                                             -\
                                                                               -\
                   ;--- Increment counter (finished?) --------------------     -\
                   #RexxVar @@Index + 1                                        -\
                   #if [@@Index > RptFileCnt]                                  -\
                       #break                                                  -\
                   #endif                                                      -\
               #}                                                              -\
                                                                               -\
               ;--- End the HTML table -----------------------------------     -\
               <$WISEINST_HTMLRPT_FILETABLE_END>                               -\
            #endif                                                             -\
                                                                               -\
            ;--- Generate SHORTCUT report --------------------------------     -\
            #if [RptScCnt = 0]                                                 -\
                <$WISEINST_HTMLRPT_NO_SHORTCUT>                                -\
            #elseif                                                            -\
               ;--- Start the HTML table ---------------------------------     -\
               <$WISEINST_HTMLRPT_HEADING TEXT="SHORTCUTS">                    -\
               <$WISEINST_HTMLRPT_SCTABLE_START>                               -\
                                                                               -\
               ;--- Sort file table entries ------------------------------     -\
               #evaluate ^^ ^call SortArray 'RptSc'^                           -\
                                                                               -\
               ;--- Generate guts of report ------------------------------     -\
               #RexxVar @@Index = 1                                            -\
               #{                                                              -\
                   ;--- Split off components -----------------------------     -\
                   #evaluate ^^ ^parse var RptSc.@@Index @@ScTitle '00'x @@ScDir '00'x @@ScTarget '00'x @@ScArgs^ -\
                   #evaluate ^^ ^@@ScTitle  = BreakAt("40-50", @@ScTitle, '\ ')^     -\
                   #evaluate ^^ ^@@ScTarget = BreakAt("40-50", @@ScTarget, '\ ')^    -\
                   #evaluate ^^ ^@@ScArgs   = BreakAt("40-50", @@ScArgs, '\ ')^      -\
                                                                               -\
                   ;--- Generate the HTML for this file ------------------     -\
                   <$WISEINST_HTMLRPT_SCTABLE_ROW>                             -\
                                                                               -\
                   ;--- Increment counter (finished?) --------------------     -\
                   #RexxVar @@Index + 1                                        -\
                   #if [@@Index > RptScCnt]                                    -\
                       #break                                                  -\
                   #endif                                                      -\
               #}                                                              -\
                                                                               -\
               ;--- End the HTML table -----------------------------------     -\
               <$WISEINST_HTMLRPT_SCTABLE_END>                                 -\
            #endif                                                             -\
                                                                               -\
            ;--- Generate REGISTRY report --------------------------------     -\
            #if [RptRegCnt = 0]                                                -\
                <$WISEINST_HTMLRPT_NO_REGISTRY>                                -\
            #elseif                                                            -\
               ;--- Start the HTML table ---------------------------------     -\
               <$WISEINST_HTMLRPT_HEADING TEXT="REGISTRY">                     -\
               <$WISEINST_HTMLRPT_REGTABLE_START>                              -\
                                                                               -\
               ;--- Sort file table entries ------------------------------     -\
               #evaluate ^^ ^call SortArray 'RptReg'^                          -\
                                                                               -\
               ;--- Generate guts of report ------------------------------     -\
               #RexxVar @@Index = 1                                            -\
               #{                                                              -\
                   ;--- Split off components -----------------------------     -\
                   #evaluate ^^ ^parse var RptReg.@@Index @@Hkey '00'x @@Key '00'x @@ValueName '00'x @@Value^ -\
                   #evaluate ^^ ^@@Key   = BreakAt("40-50", @@Key, '\ ')^      -\
                   #evaluate ^^ ^@@Value = BreakAt("20-80", @@Value, '_\ ')^   -\
                                                                               -\
                   ;--- Generate the HTML for this file ------------------     -\
                   <$WISEINST_HTMLRPT_REGTABLE_ROW>                            -\
                                                                               -\
                   ;--- Increment counter (finished?) --------------------     -\
                   #RexxVar @@Index + 1                                        -\
                   #if [@@Index > RptRegCnt]                                   -\
                       #break                                                  -\
                   #endif                                                      -\
               #}                                                              -\
                                                                               -\
               ;--- End the HTML table -----------------------------------     -\
               <$WISEINST_HTMLRPT_REGTABLE_END>                                -\
            #endif                                                             -\
                                                                               -\
            ;--- Generate SOURCE CODE report -----------------------------     -\
            #define? WISEINST_HTMLRPT_BEFORE_SOURCE_CODE                       -\
            <$WISEINST_HTMLRPT_BEFORE_SOURCE_CODE>                             -\
            #ifndef WISEINST_HTMLRPT_NO_SOURCE_CODE                            -\
               <$WISEINST_HTMLRPT_HEADING TEXT="SOURCE CODE">                  -\
               #if FindFile("HTMLPRE.IH") = ''                                 -\
                   <$WISEINST_HTMLRPT_CANT_SHOW_SOURCE>                        -\
               #elseif                                                         -\
                   ;--- Have "PRE" support -------------------------------     -\
                   #define HTMLPRE_COLOR          black                        -\
                   #define HTMLPRE_STYLE_OTHER                                 -\
                   #include "HTMLPRE.IH"                                       -\
                   <$ExampleFile FILE="<?InputFile>">                          -\
               #endif                                                          -\
            #endif                                                             -\
                                                                               -\
            ;--- Create end of Report file -------------------------------     -\
            <$WISEINST_HTMLRPT_DISCLAIMER>                                     -\
            <$WISEINST_HTMLRPT_END>                                            -\
            #output
    
    ;--- User can override these report definitions to alter look & feel --------
    #( ' '
       #define? WISEINST_HTMLRPT_DISCLAIMER                                        \
       <P>Note that this report may not show all resources of the
       types show.
       To show up in the report the developer must use
       the appropriate macros and not use "TABLE" and "ROW" directly
       etc.
       The items reported are also in summary form and other
       information can be obtained from the source listing of the
       generated WSI or MSI file.
    #)
    #define? WISEINST_HTMLRPT_HEADING                \
             <CENTER><H1>{$Text}</H1></CENTER>
    #define? WISEINST_HTMLRPT_BODY_TAG               \
             <BODY BGCOLOR="#ffe7c6">
    #define? WISEINST_HTMLRPT_FONT_STYLE             \
             font-size:80%;font-family:"Comic Sans MS","Verdana","Arial","Helvetica";
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_START
       <HTML>
       <!--- Automatically generated at <?CompileTime> --->
       <HEAD>
           <meta name="GENERATOR" content="PPWIZARD, FREE tool for Windows, OS/2, DOS and UNIX by Dennis Bareis (<?PpwizardHomePage>)">
           <TITLE><$ProductName> v<$ProductVersion></TITLE>
           <STYLE TYPE="text/css">
           <!--
               BODY {<$WISEINST_HTMLRPT_FONT_STYLE>}
               TD   {<$WISEINST_HTMLRPT_FONT_STYLE>}
               PRE  {font-size:100%;background-color: #ffffc6;color:black;display:block;white-space:pre;border:1px solid #800000;padding:5}
           -->
           </STYLE>
       </HEAD>
       <$WISEINST_HTMLRPT_BODY_TAG>
           <TABLE BORDER=0 BGCOLOR="red" WIDTH="100%" CELLPADDING=2 CELLSPACING=0><TR><TD ALIGN="CENTER">
           <FONT SIZE="+3" COLOR="white">
                  <$ProductName> v<$ProductVersion>
           </FONT></TD></TR></TABLE>
           <$WISEINST_HTMLRPT_UNDER_TITLE>
           <P>
    #)
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_END
           <P>
           <HR SIZE="1" COLOR="red">
           <CENTER>
           Created at <?CompileTime>
           <$WISEINST_HTMLRPT_FOOTER_UNDER_TIME>
           </CENTER>
       </BODY>
       </HTML>
    #)
    
    ;--- User can override these FILE report definitions to alter look & feel ---
    #define? WISEINST_HTMLRPT_NO_FILES                                          \
             <$WISEINST_HTMLRPT_HEADING TEXT="FILES">                          -\
             <P><B>There were no files in this package!</B>
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_FILETABLE_START
       <CENTER>
       <TABLE COLS="5" Border="1" Border="1" BORDERCOLOR="navy" CELLPADDING="3" cellspacing="1">
       <TR>
           <TH>Short<BR>Name</TH>
           <TH>Time</TH>
           <TH>Size</TH>
           <TH>Destination<BR>Directory</TH>
           <TH>Source</TH>
           #if [CmtFileCnt <> 0]
               <TH>Comment</TH>
           #endif
       </TR>
    #)
    #DefineRexx 'WISEINST_HTMLRPT_FILETABLE_ROW'
       H = ''
       H = H || '<TR>'
       H = H ||     '<TD>' || @@Short || '</TD>'
       H = H ||     '<TD>' || @@Date || '<BR>' || @@Time || '</TD>'
       H = H ||     '<TD ALIGN="RIGHT">' || @@Size || '</TD>'
       H = H ||     '<TD>' || @@DstDirPrettyWithAlias || '</TD>'
       H = H ||     '<TD>' || @@SrcDir || '</TD>'
       if CmtFileCnt <> 0 then
       do
           H = H || '<TD>' || @@FileCmt || '</TD>'
       end;
       H = H || '</TR>'
    #DefineRexx
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_FILETABLE_END
       </TABLE>
       <P><??RptFileCnt> File(s).
       </CENTER>
    #)
    
    
    ;--- User can override these SHORTCUT report definitions to alter look & feel ---
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_NO_SHORTCUT
       <$WISEINST_HTMLRPT_HEADING TEXT="SHORTCUTS">
       <P><B>
       <CENTER>There are no shortcuts.</CENTER>
       </B>
    #)
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_SCTABLE_START
       <CENTER>
       <TABLE COLS="4" Border="1" Border="1" BORDERCOLOR="navy" CELLPADDING="3" cellspacing="1">
       <TR>
           <TH>Title</TH>
           <TH>Location</TH>
           <TH>Target</TH>
           <TH>Arguments</TH>
       </TR>
    #)
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_SCTABLE_ROW
       <?NewLine>
       <TR>
           <TD><??@@ScTitle></TD>
           <TD><??@@ScDir></TD>
           <TD><??@@ScTarget></TD>
           <TD><??@@ScArgs></TD>
       </TR>
    #)
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_SCTABLE_END
       </TABLE>
       <P><??RptScCnt> Shortcut(s).
       </CENTER>
    #)
    
    
    ;--- User can override these REGISTRY report definitions to alter look & feel ---
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_NO_REGISTRY
       <$WISEINST_HTMLRPT_HEADING TEXT="REGISTRY">
       <P><B>
       <CENTER>There are no registry enties.</CENTER>
       </B>
    #)
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_REGTABLE_START
       <CENTER>
       <TABLE COLS="4" Border="1" Border="1" BORDERCOLOR="navy" CELLPADDING="3" cellspacing="1">
       <TR>
           <TH>HKEY<BR>(Hive)</TH>
           <TH>Key</TH>
           <TH>Value<BR>Name</TH>
           <TH>Value</TH>
       </TR>
    #)
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_REGTABLE_ROW
       <?NewLine>
       <TR>
           <TD><??@@HKey></TD>
           <TD><??@@Key></TD>
           <TD><??@@ValueName></TD>
           <TD><??@@Value></TD>
       </TR>
    #)
    #( '<?NewLine>'
       #define? WISEINST_HTMLRPT_REGTABLE_END
       </TABLE>
       <P><??RptRegCnt> Registry entries.
       </CENTER>
    #)
    
    
    ;--- User can override these SOURCE report definitions to alter look & feel ---
    #( '<?NewLine>'
       #define WISEINST_HTMLRPT_CANT_SHOW_SOURCE
       <P><B>
       Sorry but I can't display the source as the development workstation
       does not have access to the PPWIZARD add-on "HTMLPRE.IH".
       </B>
    #)
    
    ;--- Provides a few "HOOKS" for simple changes, more complex ones need overriding of above macros ---
    #define? WISEINST_HTMLRPT_FOOTER_UNDER_TIME
    #define? WISEINST_HTMLRPT_UNDER_TITLE
    


[Top][Contents][Search][Prev]: The Header File - BSD.WIH[Next]: Creating HTML pages from Windows URL Shortcuts or OS/2 URL Objects

PPWIZARD Manual
My whole website and this manual itself was developed using PPWIZARD (free preprocessor written by Dennis Bareis)
Thursday January 17 2002 at 6:27pm