Solved

Getting a files' version ID using code

Posted on 2002-03-13
13
214 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
[X]
Welcome to Experts Exchange

Add your voice to the tech community where 5M+ people just like you are talking about what matters.

  • Help others & share knowledge
  • Earn cash & points
  • Learn & ask questions
  • 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
PeopleSoft Has Never Been Easier

PeopleSoft Adoption Made Smooth & Simple!

On-The-Job Training Is made Intuitive & Easy With WalkMe's On-Screen Guidance Tool.  Claim Your Free WalkMe Account Now

 
LVL 28

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 28

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
 

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 28

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

Technology Partners: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Have you ever wanted to restrict the users input in a textbox to numbers, and while doing that make sure that they can't 'cheat' by pasting in non-numeric text? Of course you can do that with code you write yourself but it's tedious and error-prone …
If you need to start windows update installation remotely or as a scheduled task you will find this very helpful.
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…
Show developers how to use a criteria form to limit the data that appears on an Access report. It is a common requirement that users can specify the criteria for a report at runtime. The easiest way to accomplish this is using a criteria form that a…

691 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