Upgrade Code Validation |
It is possible to specify the MSI "UpgradeCode" in the version file, for example:
; Guid.UpgradeCode = {D89869CA-2A7C-3296-9CC9-038A0DEC79B8}
However doing this has one major danger! Most people will use another projects files as a basis for the new one they are building and will copy the files and make appropriate changes.
It is quite possible that the user forgets to use the GUID Generation shortcut and update the upgrade code! This results in two or more products accidently sharing an upgrade code.
The following shows some code which will over time build up a directory tree containing all the GUIDs used and the product using it, if you attempt to use a GUID used by another product then an error will result.
As written the code does not track versions of products and the code must be used before COMPANY.MMH is processed.
;--- One way of inserting the validation ------------------------------------ #define? COMPANY_UPGRADECODE_HOOK_AFTER_SETTING <$ValidateTheUpgradeCodeUsingTheGuidDirectory> ;--- The code which does the validation ------------------------------------- #define? GuidDirectory C:\Tmp\UpgradeCodeValidations ;;Network drive is a good idea as is reference via environment variable #( '<?NewLine>' ;--- Define a macro ----------------------------------------------------- #define? ValidateTheUpgradeCodeUsingTheGuidDirectory ;;Version 06.342 ;--- Make sure the "GuidDirectory" exists ------------------------------- #( '' #DefineRexx '' RxGuidDir = '<$GuidDirectory>'; if DirQueryExists(RxGuidDir) = '' then; call MakeDirectoryTree RxGuidDir; #DefineRexx #) ;--- Generate inline VBSCRIPT ------------------------------------------- <$Vbs> ;--- Comment in generated code -------------------------------------- '*** '*** Macro: "ValidateTheUpgradeCodeUsingTheGuidDirectory" '*** <?NewLine> ;--- Main directories/flags used ------------------------------------ dim GuidDir : GuidDir = "<$GuidDirectory>\" & UpgradeCode dim AppFlagFile : AppFlagFile = GuidDir & "\<$ProdInfo.ProductName>.TXT" dim ProductDir : ProductDir = "<$GuidDirectory>\$ByProduct$\<$ProdInfo.ProductName>" dim ProductFile : ProductFile = ProductDir & "\" & UpgradeCode & ".TXT" dim oValStream ;--- Has GUID been seen before? ------------------------------------- say "Checking Upgrade Code: " & UpgradeCode say "Upgrade Code Database: <$GuidDirectory>" if not oFs.FolderExists(GuidDir) then ;--- First use of this upgrade code so create the GUID dir ------ oFS.CreateFolder(GuidDir) VbsCheck "Flagging Upgrade code (GUID) use" ;--- Create a flag file ----------------------------------------- <$CreateUpgradeCodeFile FileVariable="AppFlagFile"> else ;--- Is this "our" GUID? ---------------------------------------- if not oFs.FileExists(AppFlagFile) then ;--- Display error (GUID not used by us!) ------------------- dim UsedBy, oFolder, oFiles, oFile UsedBy = "" set oFolder = oFS.GetFolder(GuidDir) set oFiles = oFolder.Files for each oFile in oFiles if ucase(oFS.GetExtensionName(oFile.name)) = "TXT" then UsedBy = UsedBy & vbCRLF & " * " & oFS.GetBaseName(oFile.name) end if next error("Incorrect use of the Upgrade Code GUID, it is used by the product(s):" & vbCRLF & UsedBy) end if end if ;--- Create another file for user lookup purposes only ---------- oShell.run "cmd.exe /c md """ & ProductDir & """", 0, true <$CreateUpgradeCodeFile FileVariable="ProductFile"> <$/Vbs> #) #( '<?NewLine>' #define CreateUpgradeCodeFile set oValStream = oFS.CreateTextFile({$FileVariable}, true) VbsCheck "Creating the upgrade code file """ & {$FileVariable} & """." oValStream.writeline "<$ProductVersion>" ;;For now only first version used VbsCheck "Writing to the upgrade code file """ & {$FileVariable} & """." oValStream.close() VbsCheck "Closing the upgrade code file """ & {$FileVariable} & """." #)