Solved

Getting a files' version ID using code

Posted on 2002-03-13
13
206 Views
Last Modified: 2010-05-02
How do I find out an EXE, Dll or OCX's version number through code?
0
Comment
Question by:Lisp
  • 7
  • 3
  • 2
  • +1
13 Comments
 
LVL 22

Expert Comment

by:rspahitz
ID: 6862997
Seems like the GetFileVersionInfo API call should do it...along with GetFileVersionInfoSize.
0
 
LVL 4

Expert Comment

by:trkcorp
ID: 6862998
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")
0
 
LVL 22

Expert Comment

by:rspahitz
ID: 6863019
Ahhh...a good use for FSO!  Looks like a winner to me!

0
 
LVL 27

Expert Comment

by:Ark
ID: 6863126
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
0
 
LVL 27

Expert Comment

by:Ark
ID: 6863170
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
0
 

Author Comment

by:Lisp
ID: 6863377
Ark,

The code doesn't compile.

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

From where should I source SFileName?
0
Find Ransomware Secrets With All-Source Analysis

Ransomware has become a major concern for organizations; its prevalence has grown due to past successes achieved by threat actors. While each ransomware variant is different, we’ve seen some common tactics and trends used among the authors of the malware.

 

Author Comment

by:Lisp
ID: 6863379
I'm also missing the sub "CopyMemory".
0
 

Author Comment

by:Lisp
ID: 6863385
And Missing "ZeroPad"
0
 

Author Comment

by:Lisp
ID: 6863390
And TrimNull
0
 

Author Comment

by:Lisp
ID: 6863392
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
0
 
LVL 27

Accepted Solution

by:
Ark earned 100 total points
ID: 6863599
Sorry.
Full source:

'=======Bas module code======
Option Explicit
Private Declare Sub CopyMemory Lib "kernel32" Alias "RtlMoveMemory" (Destination As Any, Source As Any, ByVal Length As Long)
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 sFileName 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 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

Private Function TrimNULL(ByVal str As String) As String
    If InStr(str, Chr$(0)) > 0& Then
        TrimNULL = Left$(str, InStr(str, Chr$(0)) - 1&)
    Else
        TrimNULL = str
    End If
End Function

Private Function ZeroPad(strValue As String, intLen As String) As String
    ZeroPad = Right$(String(intLen, "0") & strValue, intLen)
End Function

'========Form code========
Private Sub Command1_Click()
  MsgBox GetVersionInfo("c:\windows\system\shell32.dll")
End Sub

Cheers

0
 

Author Comment

by:Lisp
ID: 6863659
Thanks Again
0
 

Author Comment

by:Lisp
ID: 6863802
trkcorp,

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

Featured Post

How your wiki can always stay up-to-date

Quip doubles as a “living” wiki and a project management tool that evolves with your organization. As you finish projects in Quip, the work remains, easily accessible to all team members, new and old.
- Increase transparency
- Onboard new hires faster
- Access from mobile/offline

Join & Write a Comment

Introduction While answering a recent question (http://www.experts-exchange.com/Q_27402310.html) in the VB classic zone, I wrote some VB code in the (Office) VBA environment, rather than fire up my older PC.  I didn't post completely correct code o…
Most everyone who has done any programming in VB6 knows that you can do something in code like Debug.Print MyVar and that when the program runs from the IDE, the value of MyVar will be displayed in the Immediate Window. Less well known is Debug.Asse…
Get people started with the process of using Access VBA to control Excel using automation, Microsoft Access can control other applications. An example is the ability to programmatically talk to Excel. Using automation, an Access application can laun…
Get people started with the utilization of class modules. Class modules can be a powerful tool in Microsoft Access. They allow you to create self-contained objects that encapsulate functionality. They can easily hide the complexity of a process from…

707 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

13 Experts available now in Live!

Get 1:1 Help Now