Link to home
Start Free TrialLog in
Avatar of Lisp
Lisp

asked on

Getting a files' version ID using code

How do I find out an EXE, Dll or OCX's version number through code?
Avatar of rspahitz
rspahitz
Flag of United States of America image

Seems like the GetFileVersionInfo API call should do it...along with GetFileVersionInfoSize.
Avatar of trkcorp
trkcorp

You can use scriting do do this quite handily.
1. Add "Microsoft Scripting Runtime" to your references
2. Try this code:

Dim fso As New FileSystemObject
Dim sVer As String

sVer = fso.GetFileVersion("c:\winnt\system32\comdlg32.ocx")
Ahhh...a good use for FSO!  Looks like a winner to me!

Avatar of Ark
Hi
Private Declare Function GetFileVersionInfoSize Lib "version.dll" Alias "GetFileVersionInfoSizeA" (ByVal lptstrFilename As String, lpdwHandle As Long) As Long
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 VerQueryValue Lib "version.dll" Alias "VerQueryValueA" (pBlock As Any, ByVal lpSubBlock As String, lplpBuffer As Any, puLen As Long) As Long

Public Function GetVersionInfo(ByVal ResName As String) As String
   Dim arrVerInfo() As Byte
   Dim arrInfoName As Variant
   Dim arrLang(3) As Byte
   Dim sLang As String
   Dim dwBytes As Long
   Dim lpBuffer As Long
   Dim s As String
   Dim sText As String
   s = String(MAX_STRING, 0)
   Call GetModuleFileName(hModule, s, MAX_STRING)
   s = TrimNULL(s)
   dwBytes = GetFileVersionInfoSize(s, lpBuffer)
   ReDim arrVerInfo(0 To dwBytes - 1)
   Call GetFileVersionInfo(s, 0, dwBytes, arrVerInfo(0))
   arrInfoName = Array("OriginalFilename", "InternalName", "FileVersion", "FileDescription", "ProductName", "ProductVersion", "CompanyName", "LegalCopyright")
   Call VerQueryValue(arrVerInfo(0), "\VarFileInfo\Translation", lpBuffer, dwBytes)
   Call CopyMemory(arrLang(0), ByVal lpBuffer, dwBytes)
   sLang = ZeroPad(Hex(arrLang(1)), 2) & ZeroPad(Hex(arrLang(0)), 2) & ZeroPad(Hex(arrLang(3)), 2) & ZeroPad(Hex(arrLang(2)), 2)
   For i = 0 To UBound(arrInfoName) - 1
       Call VerQueryValue(arrVerInfo(0), "\StringFileInfo\" & sLang & "\" & CStr(arrInfoName(i)), lpBuffer, dwBytes)
       s = StrFromPtrA(lpBuffer)
       If s <> "" Then sText = sText & arrInfoName(i) & ":" & vbCrLf & vbTab & s & vbNewLine
   Next i
   GetVersionInfo = Trim(sText)
End Function

Cheers
Oops, sorry, above code is from my Resource Viewer sample (http://www.freevbcode.com/ShowCode.Asp?ID=3091)

Some addition:

Private Declare Function CopyStringA Lib "kernel32" Alias "lstrcpyA" (ByVal NewString As String, ByVal OldString As Long) As Long
Public Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long

Public Function StrFromPtrA(ByVal lpszA As Long, Optional nSize As Long = 0) As String
   Dim s As String, bTrim As Boolean
   If nSize = 0 Then
      nSize = lstrlenA(lpszA)
      bTrim = True
   End If
   s = String(nSize, Chr$(0))
   CopyStringA s, ByVal lpszA
   If bTrim Then s = TrimNULL(s)
   StrFromPtrA = s
End Function

'And changes:
Public Function GetVersionInfo(ByVal sFileName As String) As String '<<<CHANGED
'======Remove this=========
   s = String(MAX_STRING, 0)
   Call GetModuleFileName(hModule, s, MAX_STRING)
   s = TrimNULL(s)
'==========================
'=========Changed==========
   dwBytes = GetFileVersionInfoSize(sFileName, lpBuffer)
   ReDim arrVerInfo(0 To dwBytes - 1)
   Call GetFileVersionInfo(sFileName, 0, dwBytes, arrVerInfo(0))
'==========================

Cheers
Avatar of Lisp

ASKER

Ark,

The code doesn't compile.

Variable not defined SFileName on this line:
dwBytes = GetFileVersionInfoSize(SFilename, lpBuffer)

From where should I source SFileName?
Avatar of Lisp

ASKER

I'm also missing the sub "CopyMemory".
Avatar of Lisp

ASKER

And Missing "ZeroPad"
Avatar of Lisp

ASKER

And TrimNull
Avatar of Lisp

ASKER

This is what I have:


Option Explicit

Private Declare Function GetFileVersionInfoSize Lib "version.dll" Alias "GetFileVersionInfoSizeA" (ByVal lptstrFilename As String, lpdwHandle As Long) As Long
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 VerQueryValue Lib "version.dll" Alias "VerQueryValueA" (pBlock As Any, ByVal lpSubBlock As String, lplpBuffer As Any, puLen As Long) As Long
Private Declare Function CopyStringA Lib "kernel32" Alias "lstrcpyA" (ByVal NewString As String, ByVal OldString As Long) As Long
Private Declare Function lstrlenA Lib "kernel32" (ByVal lpString As Long) As Long

Public Function GetVersionInfo(ByVal ResName As String) As String
  Dim arrVerInfo() As Byte
  Dim arrInfoName As Variant
  Dim arrLang(3) As Byte
  Dim sLang As String
  Dim dwBytes As Long
  Dim lpBuffer As Long
  Dim s As String
  Dim sText As String
  Dim sfilename As String
  Dim i As Long
 
  dwBytes = GetFileVersionInfoSize(sfilename, lpBuffer)
  ReDim arrVerInfo(0 To dwBytes - 1)
  Call GetFileVersionInfo(sfilename, 0, dwBytes, arrVerInfo(0))
 
  arrInfoName = Array("OriginalFilename", "InternalName", "FileVersion", "FileDescription", "ProductName", "ProductVersion", "CompanyName", "LegalCopyright")
  Call VerQueryValue(arrVerInfo(0), "\VarFileInfo\Translation", lpBuffer, dwBytes)
  Call CopyMemory(arrLang(0), ByVal lpBuffer, dwBytes)
  sLang = ZeroPad(Hex(arrLang(1)), 2) & ZeroPad(Hex(arrLang(0)), 2) & ZeroPad(Hex(arrLang(3)), 2) & ZeroPad(Hex(arrLang(2)), 2)
  For i = 0 To UBound(arrInfoName) - 1
      Call VerQueryValue(arrVerInfo(0), "\StringFileInfo\" & sLang & "\" & CStr(arrInfoName(i)), lpBuffer, dwBytes)
      s = StrFromPtrA(lpBuffer)
      If s <> "" Then sText = sText & arrInfoName(i) & ":" & vbCrLf & vbTab & s & vbNewLine
  Next i
  GetVersionInfo = Trim(sText)
End Function


Public Function StrFromPtrA(ByVal lpszA As Long, Optional nSize As Long = 0) As String
  Dim s As String, bTrim As Boolean
  If nSize = 0 Then
     nSize = lstrlenA(lpszA)
     bTrim = True
  End If
  s = String(nSize, Chr$(0))
  CopyStringA s, ByVal lpszA
  If bTrim Then s = TrimNULL(s)
  StrFromPtrA = s
End Function
ASKER CERTIFIED SOLUTION
Avatar of Ark
Ark
Flag of Russian Federation image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
Avatar of Lisp

ASKER

Thanks Again
Avatar of Lisp

ASKER

trkcorp,

Please go here to collect some points relating to this question
https://www.experts-exchange.com/jsp/qManageQuestion.jsp?ta=visualbasic&qid=20276784