File Version Compare Code |
The following code demonstrates a VBSCRIPT function which will compare file version numbers such as ("5.60.1234.0001" and "5.60"). It is in the form of a macro so that you could define it in your common header file and refer to the macro in any "VbsCa" code that needed it (and an example of this is provided below as well as in the "MDAC not too old?" launch condition section).
This is the macro to define the VBSCRIPT function "CompareFileVersions()"):
;--- Define Return codes ---------------------------------------------------- #define FILEVER_RC_F1_EQUAL_F2 0 #define FILEVER_RC_F1_LESS_THAN_F2 -1 #define FILEVER_RC_F1_GREATER_THAN_F2 1 ;--- Define the macro ------------------------------------------------------- #( '<?NewLine>' ;--- Define macro used to include this code ----------------------------- #define INCLUDE_VBSCRIPT_FUNCTION-CompareFileVersions ;;Version 09.138 '======================================================================== function CompareFileVersions(VerF1, VerF2) '======================================================================== '-------- Init ------------------------------------------------------ CaDebug 0, "CompareFileVersions() """ & VerF1 & """ with """ & VerF2 & """" VbsCaLogInc 1 on error resume next CompareFileVersions = <$FILEVER_RC_F1_EQUAL_F2> '-------- Split up the version numbers ------------------------------ dim VerBitsF1 : VerBitsF1 = split(VerF1, ".") dim VerBitsF2 : VerBitsF2 = split(VerF2, ".") '-------- How many "bits" are there (use largest of the two) -------- dim LastIndex : LastIndex = ubound(VerBitsF1) if ubound(VerBitsF2) > LastIndex then LastIndex = ubound(VerBitsF2) end if '-------- Work through each of the bits (probably 4) ---------------- dim i for i = 0 to LastIndex '--- Work out the 2 "bits" to compare (use "0" on shorter versions) --- dim BitF1, BitF2 if i <= ubound(VerBitsF1) then BitF1 = VerBitsF1(i) else BitF1 = "" if i <= ubound(VerBitsF2) then BitF2 = VerBitsF2(i) else BitF2 = "" if BitF1 = "" then BitF1 = "0" ;;May as well be paranoid... if BitF2 = "" then BitF2 = "0" '-------- Compare the values (exit when mismatch found) --------- CaDebug 0, "Comparing level #" & i+1 & """: " & BitF1 & """ with """ & BitF2 & """" VbsCaLogInc 1 if cint(BitF1) > cint(BitF2) then CaDebug 0, """" & BitF1 & """ is greater than """ & BitF2 & """" CompareFileVersions = <$FILEVER_RC_F1_GREATER_THAN_F2> else if cint(BitF1) < cint(BitF2) then CaDebug 0, """" & BitF1 & """ is less than """ & BitF2 & """" CompareFileVersions = <$FILEVER_RC_F1_LESS_THAN_F2> end if end if VbsCaLogInc -1 if CompareFileVersions <> <$FILEVER_RC_F1_EQUAL_F2> then exit for next CaDebug 0, "Compare answer is " & CompareFileVersions VbsCaLogInc -1 end function #)
Custom Action To Check Installed File Version |
The following code defines a macro (which makes use of the one above) to generate custom actions to validate that an installed file has a minimum version:
#( #define FileVerMustbeAtLeast ;;Version 09.138 ;--- Adjust the value to something Windows Installer can compare ---- <$VbsCa Binary="FileVer_{$File}_MustbeAtLeast.vbs" DATA="{$File}"> #( '<?NewLine>' <$VbsCaEntry "ValidateFileVersion"> ;--- Init (get "passed" parameters) ----------------------------- dim VerMin : VerMin = VbsCaCadGet("VerMin") dim FileName : FileName = VbsCaCadGet("FileName") CaDebug 1, "Verifying version of """ & FileName & """" VbsCaLogInc 1 ;--- Now Get the file version ----------------------------------- dim VerFile : VerFile = GetFileVersion(FileName) CaDebug 2, "Version is " & VerFile ;--- Compare ------------------------------------------------ CaDebug 0, "Comparing the versions..." dim CompRc, PropertyValue CompRc = CompareFileVersions(VerFile, VerMin) if CompRc <> <$FILEVER_RC_F1_EQUAL_F2> and CompRc = <$FILEVER_RC_F1_LESS_THAN_F2> then VbsCaRaiseError "ValidateFileVersion()", "The file """ & FileName & """ has version " & VerFile & vbCRLF & vbCRLF & "This doesn't meet the minimum requirement of version " & VerMin end if CaDebug 0, "Version of the file is OK..." ;--- set the property --------------------------------------- VbsCaLogInc -1 <$/VbsCaEntry> <?NewLine><?NewLine> '++++++++++++++++++++++++++++++++ function GetFileVersion(FileName) '++++++++++++++++++++++++++++++++ ;--- Make sure the file exists ---------------------------------- dim oFS : set oFS = CaMkObject("Scripting.FileSystemObject") if not oFS.FileExists(FileName) then VbsCaRaiseError "ValidateFileVersion()", "The file """ & FileName & """ doesn't exist!" end if set oFS = Nothing ;--- Get the file info ------------------------------------------ dim oInstaller : set oInstaller = CaMkObject("WindowsInstaller.Installer") on error resume next GetFileVersion = oInstaller.FileVersion(FileName, 0) if err.number <> 0 then dim Reason : Reason = "0x" & hex(err.number) & " - " & err.description on error goto 0 VbsCaRaiseError "ValidateFileVersion()", "Couldn't get the file version for """ & FileName & """." & vbCRLF & vbCRLF & "Reason: " & Reason end if ;--- Term ------------------------------------------------------- set oInstaller = Nothing end function ;--- Add required compare function(s) ---------------------------- <$INCLUDE_VBSCRIPT_FUNCTION-CompareFileVersions> #) <$/VbsCa> <$VbsCaSetup Binary="FileVer_{$File}_MustbeAtLeast.vbs" Key="FileVer_{$File}" Entry="ValidateFileVersion" Seq="InstallInitialize-" CONDITION=^<$CONDITION_INSTALL_ONLY>^ DATA="{$File}"> #)
Now that you have defined the two macros above you can use them as follows:
#data "userenv_dll" "FileName" "[SystemFolder]userenv.dll" ;;Full name of the file "VerMin" '5.00.2195.3652' ;;Minimum version we want #data <$FileVerMustbeAtLeast File="userenv_dll">