Version of a file in VBA


I'm trying to find the version of a file using VBA. What i've been trying to do is run the filever command in CMD via Shell, but can't seem to get this to output the result to a variable.

Is this possible, to populate a string variable with the results of a shell command?

Is there another way to find this?

Who is Participating?

Improve company productivity with a Business Account.Sign Up

RgGray3Connect With a Mentor Commented:
Shell happen in their own memory...   making communication difficult...

Does the process you are running in the shell... allow redirection...?

YourCmdToFindVersion > SomeTextFile.txt

If so you can redirect the output to a text file and READ the text file using FSO.

What are you using to determine the version number and version of What?

If you are looking to find a file version of a Dll or something.. you are better off using an API call to retrieve the value...

See the attached code
' --------------------------------------------------------------------
' Module     : usys_GetOLEAut32VersionInfo_bas
' Description:
' Procedures : IsOLELibNewer()
'              GetResourceVersion(strFileName As String, recFileVer As FileVersion)
' Copyright  : 2005-2011
'              Richard Gray, III Software
'              All rights reserved.
' --------------------------------------------------------------------
Option Compare Database
Option Explicit

' API Calls for getting a file's version information
Private Type FileVersion
    FileVersion         As String         ' Full file version as a string
    FileVersionMSl      As Integer        ' File version MSB Low
    FileVersionMSh      As Integer        ' File version MSB High
    FileVersionLSl      As Integer        ' File version LSB Low
    FileVersionLSh      As Integer        ' File version LSB High
    ProductVersion      As String         ' File product version as a string
    ProductVersionMSl   As Integer        ' Product version MSB low
    ProductVersionMSh   As Integer        ' Product version MSB high
    ProductVersionLSl   As Integer        ' Product version LSB low
    ProductVersionLSh   As Integer        ' Product version LSB high
End Type

    dwSignature         As Long
    dwStrucVersionl     As Integer
    dwStrucVersionh     As Integer
    dwFileVersionMSl    As Integer
    dwFileVersionMSh    As Integer
    dwFileVersionLSl    As Integer
    dwFileVersionLSh    As Integer
    dwProductVersionMSl As Integer
    dwProductVersionMSh As Integer
    dwProductVersionLSl As Integer
    dwProductVersionLSh As Integer
    dwFileFlagsMask     As Long
    dwFileFlags         As Long
    dwFileOS            As Long
    dwFileType          As Long
    dwFileSubtype       As Long
    dwFileDateMS        As Long
    dwFileDateLS        As Long
End Type

Private Declare Function GetFileVersionInfo Lib "Version.dll" _
                  Alias "GetFileVersionInfoA" (ByVal lptstrFilename As String, _
                                               ByVal dwHandle As Long, _
                                               ByVal dwLen As Long, _
                                                     lpData As Any) As Long

Private Declare Function GetFileVersionInfoSize Lib "Version.dll" _
                  Alias "GetFileVersionInfoSizeA" (ByVal lptstrFilename As String, _
                                                         lpdwHandle As Long) As Long

Private Declare Function VerQueryValue Lib "Version.dll" _
                  Alias "VerQueryValueA" (pBlock As Any, _
                                    ByVal lpSubBlock As String, _
                                          lplpBuffer As Any, _
                                          puLen As Long) As Long

Private Declare Sub MoveMemory Lib "kernel32" _
             Alias "RtlMoveMemory" (dest As Any, _
                              ByVal Source As Long, _
                              ByVal Length As Long)

Public Sub GetResourceVersion(strFilename As String, _
                                recFileVer As FileVersion)
' --------------------------------------------------------------------
' Comments  :
' Parameters: strFileName
'             recFileVer -
' Modified  :
' --------------------------------------------------------------------
' Comments  : Returns file version information
' Parameters: strFileName - Name of the file
'             recFileVer - FILEVERSION type
' Returns   : Nothing
' --------------------------------------------------------------------
Dim lngRC As Long
Dim lngDummy As Long
Dim abytBuffer() As Byte
Dim lngBufferLen As Long
Dim lngVerPointer As Long
Dim lngVerbufferLen As Long

On Error GoTo PROC_ERR
    ' Get the size
    lngBufferLen = GetFileVersionInfoSize(strFilename, lngDummy)
    If lngBufferLen < 1 Then
        Exit Sub
    End If
    ' Set up the byte array
    ReDim abytBuffer(lngBufferLen)
    ' Get the file version information
    lngRC = GetFileVersionInfo(strFilename, 0&, lngBufferLen, abytBuffer(0))
    lngRC = VerQueryValue(abytBuffer(0), "\", lngVerPointer, lngVerbufferLen)
    ' Manipulate the bits
    MoveMemory udtVerBuffer, lngVerPointer, Len(udtVerBuffer)
    ' Build the file version string
    With recFileVer
        .FileVersion = Format$(udtVerBuffer.dwFileVersionMSh) & "." & _
                       Format$(udtVerBuffer.dwFileVersionMSl) & "." & _
                       Format$(udtVerBuffer.dwFileVersionLSh) & "." & _
        .FileVersionLSh = udtVerBuffer.dwFileVersionLSh
        .FileVersionLSl = udtVerBuffer.dwFileVersionLSl
        .FileVersionMSh = udtVerBuffer.dwFileVersionMSh
        .FileVersionMSl = udtVerBuffer.dwFileVersionMSl
    ' Build the product version string
        .ProductVersion = Format$(udtVerBuffer.dwProductVersionMSh) & "." & _
                                Format$(udtVerBuffer.dwProductVersionMSl) & "." & _
                                Format$(udtVerBuffer.dwProductVersionLSh) & "." & _
        .ProductVersionLSh = udtVerBuffer.dwProductVersionLSh
        .ProductVersionLSl = udtVerBuffer.dwProductVersionLSl
        .ProductVersionMSh = udtVerBuffer.dwProductVersionMSh
        .ProductVersionMSl = udtVerBuffer.dwProductVersionMSl
    End With
    Exit Sub
    MsgBox "Error: " & Err.Number & ". " & Err.Description, , _
    Resume PROC_EXIT
End Sub

Public Sub TestFileVer()
Dim strFile As String
Dim recFile As FileVersion

    strFile = "avmeter.dll"
    GetResourceVersion strFile, recFile
    Debug.Print recFile.FileVersion
    Debug.Print recFile.ProductVersion
End Sub

Open in new window

Scott McDaniel (Microsoft Access MVP - EE MVE )Infotrakker SoftwareCommented:
That would depend on what the Shell command's called program returns. In most cases, the result isn't what you're after.

You can use several methods to find this out, however. The FileSystemObject can do this:
Simple solution is to use DSOfile.dll from microsoft. Get more details from
Get 10% Off Your First Squarespace Website

Ready to showcase your work, publish content or promote your business online? With Squarespace’s award-winning templates and 24/7 customer service, getting started is simple. Head to and use offer code ‘EXPERTS’ to get 10% off your first purchase.

Is this possible, to populate a string variable with the results of a shell command?
The short answer is YES

I'm not sure if you have been able to get the version, but I'll tell you how just incase.

The easiest method would be to extract the "filever.exe" from the file in a windows cd located at drive:\SUPPORT\TOOLS\SUPPORT.CAB - You can open it with Windows Explorer, Winzip etc. From there you can use the filever.exe to get the file version of pretty much anything, the full explanation is at - it will explain everything it outputs. an example usage of it would be:
C:\filever.exe myTestFile.exe

Open in new window

which would output something similar to:
--a-- W32i   APP   -  3.1.4007.24314 shp  6,488,064 12-21-2010 myTestFile.exe

What I've done for the VB example, is I've created two buttons, one button creates a batch file (which contains my shell command), and the other starts it, reads the output, stores it in a string variable, and displays it in a message box, then deletes the batch file.

This is certainly the easiest way to do this, either creating or accessing a batch file, because otherwise you're going to be trying to access specific windows and controlling them etc.

Here's what i did:

Button1 creates the batch file (Note: This is unneeded, it's here to show you how to create one from VB, you can just access anything directly from the Button2)

Required Imports:
Imports System.IO

Open in new window

Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        Dim oWriter As StreamWriter
        oWriter = My.Computer.FileSystem.OpenTextFileWriter(Application.StartupPath + "\test.bat", True, System.Text.Encoding.ASCII)
        oWriter.WriteLine("@echo off" & Chr(13))
        oWriter.WriteLine("echo This Is A Test")
End Sub

    Private Sub Button2_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button2.Click
Dim process As New Process()
        Dim FileName As String = Application.StartupPath + "\test.bat"
        process.StartInfo.UseShellExecute = False
        process.StartInfo.RedirectStandardOutput = True
        process.StartInfo.RedirectStandardError = True
        process.StartInfo.CreateNoWindow = True
        process.StartInfo.FileName = FileName
        Dim output As String = process.StandardOutput.ReadToEnd()
End Sub

Open in new window

When you select Button2 you will get a message box saying "This Is A Test".

Basically, it is just starting a new process with the file you tell it to, and redirecting the standard output to your application for reading. Very simple, and it works.

Hopefully this answered your question,

It looks like you've posted VB.Net code.  This is a VBA runtime environment.
This is an example of using FSO in a VBA environment:

Dim objFSO As Object
Set objFSO = CreateObject("Scripting.FileSystemObject")
Debug.Print objFSO.GetFileVersion("path and file name")

Set objFSO = Nothing

Open in new window

@aikimark yes, it's, sorry I forgot to mention that, I posted that to merely set him on the right track as from my understanding, VBA uses the same 'base' for programming and are fairly similar. The oWriter was purely informational as it isn't required for the other code to work. I'm on the road atm so I can't check but I'm sure there are plenty VB.Net to VBA converters. I'll post back later tonight when I'm back home or in the office.

FIY to all

If you explicitly declare your fso object as a NEW FileSystemObject you will expose intellisense and see all of the methods and properties.

Dim objFSO     As New FileSystemObject

    Set objFSO = CreateObject("Scripting.FileSystemObject")  
    strYourVar =  objFSO.GetFileVersion("path and file name")  

I wish there were an early binding method for WMI

I haven't found any.  How are you at doing the conversion manually?  There is another EE question where that expertise is needed.

>>I wish there were an early binding method for WMI
Add this reference:
Microsoft WMI Scripting V1.2 Llibrary
ITUCIRLAuthor Commented:
I've rolled out Flash and Shockwave via GPO, and i was going to use VBA in Access to check the versions to make sure they're the most up-to-date.

I have all of my client PCs in a table, so i was going to use a loop to check each one, and if it is older than the current version, to print the PC name to a text box, or a text file.
Scott McDaniel (Microsoft Access MVP - EE MVE )Infotrakker SoftwareCommented:
Was you last comment something that we need to take into consideration regarding this question? Because it seems your original question has been well answered by any of several comments. If you need further help building the loop and such, you probably should ask a new question.
ITUCIRLAuthor Commented:
i was just giving a bit more info. I'll have a go at some of these methods.

Thanks guys.
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.