![]() | ![]() | ![]() | ![]() | ![]() |
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 #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. 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=" "> ;--- 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
![]() | ![]() | ![]() | ![]() | ![]() |