\
Tips and Tricks
File and Directory
File Version Compare Code
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">