As a key part of the Install.cmd script, there is a check for an existing installation of the software and, if found, which version it is. To facilitate that, we developed this CheckVersion.vbs script.

There are actually three different flavors of code here:

  1. Registry Key Version - Obtains the version of the software from a registry key. An exact key match is used to locate and obtain the data.
  2. File Version - Obtains the version of the software from a file header. An exact file match is used to locate and obtain the data.
  3. MSI Version - Obtains the version of the software from the MSI registry database. A WMI query of all installed MSI software is used to locate the installation instance, which is then used to locate the version data from the registry.

To create your script, you should select the first half from one of the three styles and paste that into an editor. Customize the constants to locate the correct values. Then, copy the second half from the snippet below. This second half is common across all three types.

Registry Key Version

The below snippet is the first half of the code for the Registry Key Version of CheckVersion.vbs. To customize this, edit the three constants Base32, Base64, and VersionValue with items that are appropriate for your software. The rest of the code performs the necessary instantiation of objects and performs the registry key lookup.

'This script will check the version for ReplaceWithSoftwareName
'Requires the parameter: /MinVer:A.B.C.D
'Exit code of 0 indicates script error
'Exit code of 2 indicates that no version is installed
'Exit code of 3 indicates that an old version is installed
'Exit code of 4 indicates that the current or a newer version is installed

'Customize these values for this software.
Const Base32 = "SOFTWARE\ReplaceThisKeyPath"
Const Base64 = "SOFTWARE\Wow6432Node\ReplaceThisKeyPath"
Const VersionValue = "ReplaceWithVersionValueName"

Set WMI = GetObject("winmgmts://./root/default")
Set REG = WMI.Get("StdRegProv")
Set SO = WScript.StdOut

Const HKLM = &H80000002

'Determine if we are 32-bit, 64-bit, or if the app isn't installed
SO.WriteLine "Checking for previous installation..."
Result = REG.CheckAccess(HKLM, Base32, 3, bGranted)
if bGranted then
    SO.WriteLine "...found registry key (32)."
	Base = Base32
else
    Result = REG.CheckAccess(HKLM, Base64, 3, bGranted)
	if bGranted Then
	    SO.WriteLine "...found registry key (64)."
		Base = Base64
	else
	    'Not found
		SO.WriteLine "...no installation found."
		WScript.Quit 2
	end if
end if

'Grab the version from the registry and clean it up
Result = REG.GetStringValue(HKLM, Base, VersionValue, VerRaw)
If Result <> 0 Then
    SO.WriteLine "No version currently installed."
	WScript.Quit 2
End If
SO.WriteLine "Current version installed: " & VerRaw
TestVer = VersionCleanup(VerRaw)

File Version

The below snippet is the first half of the code for the File Version of CheckVersion.vbs. To customize this, edit the three constants Base32, Base64, and FileName with items that are appropriate for your software. The rest of the code performs the necessary instantiation of objects and performs the file version lookup.

'This script will check the version for ReplaceWithSoftwareName
'Requires the parameter: /MinVer:A.B.C.D
'Exit code of 0 indicates script error
'Exit code of 2 indicates that no version is installed
'Exit code of 3 indicates that an old version is installed
'Exit code of 4 indicates that the current or a newer version is installed

Set WMI = GetObject("winmgmts://./root/default")
Set SO = WScript.StdOut
Set FSO = CreateObject("Scripting.FileSystemObject")
Set wshShell = CreateObject("WScript.Shell")

'Customize these constants for your software
Const Base32 = wshShell.ExpandEnvironmentStrings("%ProgramFiles(x86)%\ReplaceThisFolderPath")
Const Base64 = wshShell.ExpandEnvironmentStrings("%ProgramFiles%\ReplaceThisFolderPath")
Const FileName = "ReplaceWithFileName"

'Determine if we are 32-bit, 64-bit, or if the app isn't installed
SO.WriteLine "Checking for previous installation..."
Result = FSO.FolderExists(Base32)
if Result then
    SO.WriteLine "...found folder path (32)."
    Base = Base32
else
    Result = FSO.FolderExists(Base64)
    if Result Then
        SO.WriteLine "...found folder path (64)."
        Base = Base64
    else
        'Not found
        SO.WriteLine "...no installation found."
        WScript.Quit 2
    end if
end if

'Grab the version from the file and clean it up
Result = FSO.FileExists(Base & "\" & FileName)
If Not Result Then
    SO.WriteLine "No version currently installed."
    WScript.Quit 2
End If
Set F = WMI.Get("cim_datafile.Name='" & Replace(Base & "\" & FileName, "\", "\\") & "'")
VerRaw = F.Version
SO.WriteLine "Current version installed: " & VerRaw
TestVer = VersionCleanup(VerRaw)

MSI Version

The below snippet is the first half of the code for the MSI Version of CheckVersion.vbs. To customize this, edit the two constants Query and VersionValue with items that are appropriate for your software. The rest of the code performs the MSI search and the version lookup.

'This script will check the version for ReplaceWithSoftwareName
'Requires the parameter: /MinVer:A.B.C.D
'Exit code of 0 indicates script error
'Exit code of 2 indicates that no version is installed
'Exit code of 3 indicates that an old version is installed
'Exit code of 4 indicates that the current or a newer version is installed

'Customize these constants for your software
Const Query = "%SoftwareName%"
Const VersionValue = "DisplayVersion"

Set wshShell = CreateObject("WScript.Shell")
Set WMI = GetObject("winmgmts://./root/cimv2")
Set SO = WScript.StdOut Const

HKLM = &H80000002

'Query the MSI registry database for the application
SO.WriteLine "Checking for previous installation..."
Set Products = WMI.ExecQuery("Select * from Win32_Product where Name like '" & Query & "'")
If Products.Count = 0 Then
    SO.WriteLine "...no installation found."
    WScript.Quit 2
End If

TestVer = ""

For Each Product in Products
    ID = Product.IdentifyingNumber
    On Error Resume Next
    TestVer = wshShell.RegRead("HKLM\SOFTWARE\Wow6432Node\Microsoft\Windows\CurrentVersion\Uninstall\" & ID & "\" & VersionValue)
    TestVer = wshShell.RegRead("HKLM\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\" & ID & "\" & VersionValue)
    On Error Goto 0
Next
If TestVer = "" Then
    SO.WriteLine "...no installation found."
    WScript.Quit 2
Else
    SO.WriteLine "...found product installed."
End If

TestVer = VersionCleanup(TestVer)

Common Second Half of Script

This snippet below is the common second half of the script. Here's what it does:

  1. Obtain the minimum version required from the command line parameter /MinVer:
  2. Split the versions on the period (.) character into arrays.
  3. Build comparison strings by right-justifying each part of the version number so that each version has the same number of characters. The padding character is the zero.
  4. Compare the strings and determine if we have a newer version number installed or not.

The rest of the script contains helper functions that clean up version strings (like changing spaces into periods), handle the padding of strings, and determine the maximum of two values.

'Grab the minimum version from the command line
MinVer = VersionCleanup(WScript.Arguments.Named("MinVer"))
SO.WriteLine "Minimum version needed : " & MinVer
if MinVer = "" Then
    SO.WriteLine "!! ERROR !! - Need to have MinVer specified"
	WScript.Quit 0
end if

'Split the versions into arrays
VMin = Split(MinVer,".")
VTest = Split(TestVer,".")

'Initialize some variables
SMin = ""
STest = ""

'Start by iterating through each part of the MinVer version.
For I = LBound(VMin) to UBound(VMin)
    If I <= UBound(VTest) then
	    'We have a corresponding TestVer part
		SMin = SMin & Padded(VMin(I),Max(Len(VMin(I)),Len(VTest(I))))
		STest = STest & Padded(VTest(I),Max(Len(VMin(I)),Len(VTest(I))))
	Else
	    'No part from TestVer
		SMin = SMin & VMin(I)
		STest = STest & Padded("0",Len(VMin(I)))
	End If
Next

'Continue by iterating through any TestVer parts after the MinVer parts
For I = (UBound(VMin)+1) To UBound(VTest)
    SMin = SMin & Padded("0",Len(VTest(I)))
	STest = STest & VTest(I)
Next

'Perform a simple string comparison to determine results
If StrComp(SMin,STest,1) < 1 Then
    SO.Writeline "The current or a newer version is installed."
	WScript.Quit 4
Else
    SO.WriteLIne "An older version is installed."
	WScript.Quit 3
End If


'Helper functions

Function VersionCleanup(strIn)
    'Cleans up the version so that spaces are replaced
	VersionCleanup = Replace(strIn," ",".")
End Function

Function Padded(strIn,lLen)
    Padded = String(lLen - Len(strIn),"0") & strIn
	'SO.WriteLine "PADDED " & strIn & " " & Len(strIn) & " " & lLen & " " & Padded
End Function

Function Max(A,B)
    If A > B Then
	    Max = A
    Else
	    Max = B
    End If
End Function