How to Use Functions in VER.DLL--A 16-Bit Sample Application

Last reviewed: May 2, 1996
Article ID: Q112731
The information in this article applies to:
  • Standard and Professional Editions of Microsoft Visual Basic for Windows, versions 2.0 and 3.0
  • Professional and Enterprise Editions of Microsoft Visual Basic, 16-bit only, for Windows, version 4.0

SUMMARY

This article contains code and instructions that show you how to create a sample application that uses some of the functions in VER.DLL to retrieve file information embedded into a file with the resource compiler (RC.EXE).

NOTE: This code works in Visual Basic, versions 2.0, 3.0, or 4.0 16-bit only, for Windows, but not in Visual Basic, version 4.0, 32-bit only, for Windows. To obtain a Visual Basic, version 4.0, 32-bit only, for Windows, example of this code, please see the following article in the Microsoft Knowledge Base:

   ARTICLE-ID: Q139491
   TITLE     : How to Use Functions in VERSION.DLL -- a 32-bit Sample
               App

This Visual Basic application was modeled after the Verstamp sample program included in the Microsoft Windows Software Development Kit (SDK).

Additional information can be found in the following documents:

  • Microsoft Windows 3.1 Programmer's Reference, Vols. 2 & 3
  • Microsoft SDK Reference Help File (WIN31WH.HLP) from Windows 3.1 SDK or the Professional Edition of Visual Basic version 2.0 or 3.0.

MORE INFORMATION

Instead of offering this article in a number of steps, we have modified our usual format to make it easier for you to create and use this Visual Basic application. Therefore, the three files you need (VERINFO.BAS, VERINFO1.FRM, VERINFO2.FRM) are listed below so you can easily copy them into a text editor and save them as separate files. Instructions for how to use the files are embedded in the files as comments.

VERINFO.BAS

' Place the following code in a single text file called VERINFO.BAS
'
' The Global constants below are defined in the VER.H header file, also
' included in Microsoft C/C++ 7.0, and the Windows SDK.
'
' NOTE: After copying this into a file in a text editor, modify each
' Declare statements so that each one uses only one, single line.

Type VS_VERSION
   wLength            As Integer
   wValueLength       As Integer
   szKey              As String * 16 ' "VS_VERSION_INFO"
   dwSignature        As Long        ' VS_FIXEDFILEINFO struct
   dwStrucVersion     As Long
   dwFileVersionMS    As Long
   dwFileVersionLS    As Long
   dwProductVersionMS As Long
   dwProductVersionLS As Long
   dwFileFlagsMasks   As Long
   dwFileFlags        As Long
   dwFileOS           As Long
   dwFileType         As Long
   dwFileSubType      As Long
   dwFileDateMS       As Long
   dwFileDateLS       As Long
End Type

Declare Function GetFileVersionInfo% Lib "Ver.dll" (ByVal Filename$,
   ByVal dwhandle&, ByVal cbBuff&, ByVal lpvData$)
Declare Function GetFileVersionInfoSize& Lib "Ver.dll"
   (ByVal Filename$, dwhandle&)
Declare Sub hmemcpy Lib "kernel" (hpvDest As Any, hpvSrc As Any,
   ByVal cbBytes&)
Declare Function GetSystemDirectory% Lib "kernel"
   (ByVal Path$, ByVal cbBytes%)

' **** VS_VERSION.dwFileFlags ****
Global Const VS_FF_DEBUG = &H1& Global Const VS_FF_PRERELEASE = &H2& Global Const VS_FF_PATCHED = &H4& Global Const VS_FF_PRIVATEBUILD = &H8& Global Const VS_FF_INFOINFERRED = &H10& Global Const VS_FF_SPECIALBUILD = &H20&

' **** VS_VERSION.dwFileOS ****
Global Const VOS_UNKNOWN = &H0& Global Const VOS_DOS = &H10000 Global Const VOS_OS216 = &H20000 Global Const VOS_OS232 = &H30000 Global Const VOS_NT = &H40000

Global Const VOS__BASE = &H0& Global Const VOS__WINDOWS16 = &H1& Global Const VOS__PM16 = &H2& Global Const VOS__PM32 = &H3& Global Const VOS__WINDOWS32 = &H4&

Global Const VOS_DOS_WINDOWS16 = &H10001 Global Const VOS_DOS_WINDOWS32 = &H10004 Global Const VOS_OS216_PM16 = &H20002 Global Const VOS_OS232_PM32 = &H30003 Global Const VOS_NT_WINDOWS32 = &H40004

' **** VS_VERSION.dwFileType ****
Global Const VFT_UNKNOWN = &H0& Global Const VFT_APP = &H1& Global Const VFT_DLL = &H2& Global Const VFT_DRV = &H3& Global Const VFT_FONT = &H4& Global Const VFT_VXD = &H5& Global Const VFT_STATIC_LIB = &H7&

' **** VS_VERSION.dwFileSubtype for VFT_WINDOWS_DRV ****
Global Const VFT2_UNKNOWN = &H0& Global Const VFT2_DRV_PRINTER = &H1& Global Const VFT2_DRV_KEYBOARD = &H2& Global Const VFT2_DRV_LANGUAGE = &H3& Global Const VFT2_DRV_DISPLAY = &H4& Global Const VFT2_DRV_MOUSE = &H5& Global Const VFT2_DRV_NETWORK = &H6& Global Const VFT2_DRV_SYSTEM = &H7& Global Const VFT2_DRV_INSTALLABLE = &H8& Global Const VFT2_DRV_SOUND = &H9& Global Const VFT2_DRV_COMM = &HA&

' **** VS_VERSION.dwFileSubtype for VFT_WINDOWS_FONT ****
Global Const VFT2_FONT_RASTER = &H1& Global Const VFT2_FONT_VECTOR = &H2& Global Const VFT2_FONT_TRUETYPE = &H3&

' **** Global variables used in both forms ****
Global Filename$ Global Directory$ Global FileVer$ Global ProdVer$ Global FileFlags$ Global FileOS$ Global FileType$ Global FileSubType$

VERINFO1.FRM

' The following is a text dump of the form VERINFO1. It includes the form
' and control description as well as necessary Function and Sub procedures.
' Save the code in a single TEXT file called VERINFO1.FRM and you will
' be able to load it as a form in Visual Basic.
'
' NOTE: To make the code fit in this article, some of the lines are listed
' using multiple lines. After copying the code into a file in a text editor
' modify it to ensure that all lines of code exist as one, single line
' in the file. Otherwise, you will receive errors when loading the form in
' Visual Basic.

Begin Form Form1
   BorderStyle     =   1  'Fixed Single
   Caption         =   "VerInfo Demo"
   ClientHeight    =   4290
   ClientLeft      =   2340
   ClientTop       =   2160
   ClientWidth     =   3855
   Height          =   4695
   Left            =   2280
   LinkMode        =   1  'Source
   LinkTopic       =   "Form1"
   ScaleHeight     =   17.875
   ScaleMode       =   4  'Character
   ScaleWidth      =   32.125
   Top             =   1815
   Width           =   3975
   Begin DriveListBox Drive1
      Height          =   288
      Left            =   1836
      TabIndex        =   7
      Top             =   3792
      Width           =   1908
   End
   Begin DirListBox Dir1
      Height          =   1884
      Left            =   1830
      TabIndex        =   5
      Top             =   1428
      Width           =   1896
   End
   Begin FileListBox File1
      Height          =   2955
      Left            =   120
      TabIndex        =   3
      Top             =   984
      Width           =   1575
   End
   Begin TextBox Text1
      Height          =   288
      Left            =   1092
      TabIndex        =   1
      Text            =   "*.*"
      Top             =   204
      Width           =   2544
   End
   Begin Label Label1
      Caption         =   "Dri&ves:"
      Height          =   216
      Index           =   4
      Left            =   1830
      TabIndex        =   6
      Top             =   3480
      Width           =   660
   End
   Begin Label Label1
      Caption         =   "&Directories:"
      Height          =   192
      Index           =   3
      Left            =   1830
      TabIndex        =   4
      Top             =   1104
      Width           =   1236
   End
   Begin Label Label1
      Caption         =   "c:\"
      Height          =   204
      Index           =   2
      Left            =   1830
      TabIndex        =   8
      Top             =   648
      Width           =   1884
   End
   Begin Label Label1
      Caption         =   "&Files:"
      Height          =   204
      Index           =   0
      Left            =   120
      TabIndex        =   2
      Top             =   648
      Width           =   612
   End
   Begin Label Label1
      Caption         =   "File&Name:"
      Height          =   204
      Index           =   1
      Left            =   120
      TabIndex        =   0
      Top             =   252
      Width           =   936
   End
End

Sub Dir1_Change ()
   File1.Path = Dir1.Path
   Label1(2).Caption = File1.Path
End Sub

Sub DisplayVerInfo ()
   Dim X As VS_VERSION

   '*** Get Version Info ****
   FileVer$ = "": ProdVer$ = "": FileFlags$ = ""
   FileOS$ = "": FileType$ = "": FileSubType$ = ""
   FileName$ = File1.List(File1.ListIndex)
   Directory$ = Label1(2).Caption
   FullFileName$ = Label1(2).Caption + "\" + FileName$
   BufSize& = GetFileVersionInfoSize(FullFileName$, dwHandle&)
   If BufSize& = 0 Then
      MsgBox "No Version Info available!"
      Exit Sub
   End If
   lpvData$ = Space$(BufSize&)
   r% = GetFileVersionInfo(FullFileName$, dwHandle&, BufSize&, lpvData$)
   hmemcpy X, ByVal lpvData$, Len(X)

   '**** Determine File Version number ****
   FileVer$ = LTrim$(Str$(HIWORD(X.dwFileVersionMS))) + "."
   FileVer$ = FileVer$ + LTrim$(Str$(LOWORD(X.dwFileVersionMS))) + "."
   FileVer$ = FileVer$ + LTrim$(Str$(HIWORD(X.dwFileVersionLS))) + "."
   FileVer$ = FileVer$ + LTrim$(Str$(LOWORD(X.dwFileVersionLS)))

   '**** Determine Product Version number ****
   ProdVer$ = LTrim$(Str$(HIWORD(X.dwFileVersionMS))) + "."
   ProdVer$ = ProdVer$ + LTrim$(Str$(LOWORD(X.dwProductVersionMS))) +
"."
   ProdVer$ = ProdVer$ + LTrim$(Str$(HIWORD(X.dwProductVersionLS))) +
"."
   ProdVer$ = ProdVer$ + LTrim$(Str$(LOWORD(X.dwProductVersionLS)))

   '**** Determine Boolean attributes of File ****
   If X.dwFileFlags And VS_FF_DEBUG Then FileFlags$ = "DeBug"
   If X.dwFileFlags And VS_FF_PRERELEASE Then FileFlags$ =
      FileFlags$ + "PreRel"
   If X.dwFileFlags And VS_FF_PATCHED Then FileFlags$ =
      FileFlags$ + "Patched"
   If X.dwFileFlags And VS_FF_PRIVATEBUILD Then FileFlags$ =
      FileFlags$ +  "Private"
   If X.dwFileFlags And VS_FF_INFOINFERRED Then FileFlags$ =
      FileFlags$ + "Info"
   If X.dwFileFlags And VS_FF_DEBUG Then FileFlags$ =
      FileFlags$ + "Special"

   If X.dwFileFlags And &HFFFFFF00 Then FileFlags$ = FileFlags$ + "Unknown"

   '**** Determine OS for which file was designed ****
   Select Case X.dwFileOS
      Case VOS_DOS_WINDOWS16
         FileOS$ = "DOS-Win16"
      Case VOS_DOS_WINDOWS32
         FileOS$ = "DOS=Win32"
      Case VOS_OS216_PM16
         FileOS$ = "OS/2-16 PM-16"
      Case VOS_OS232_PM32
         FileOS$ = "OS/2-32 PM-32"
      Case VOS_NT_WINDOWS32
         FileOS$ = "NT-Win32"
      Case Else
         FileOS$ = "Unknown"
   End Select

   '**** Determine Type and SubType of File ****
   Select Case X.dwFileType
      Case VFT_APP
         FileType$ = "App"
      Case VFT_DLL
         FileType$ = "DLL"
      Case VFT_DRV
         FileType$ = "Driver"
         Select Case X.dwFileSubType
            Case VFT2_DRV_PRINTER
               FileSubType$ = "Printer drv"
            Case VFT2_DRV_KEYBOARD
               FileSubType$ = "Keyboard drv"
            Case VFT2_DRV_LANGUAGE
               FileSubType$ = "Language drv"
            Case VFT2_DRV_DISPLAY
               FileSubType$ = "Display drv"
            Case VFT2_DRV_MOUSE
               FileSubType$ = "Mouse drv"
            Case VFT2_DRV_NETWORK
               FileSubType$ = "Network drv"
            Case VFT2_DRV_SYSTEM
               FileSubType$ = "System drv"
            Case VFT2_DRV_INSTALLABLE
               FileSubType$ = "Installable"
            Case VFT2_DRV_SOUND
               FileSubType$ = "Sound drv"
            Case VFT2_DRV_COMM
               FileSubType$ = "Comm drv"
            Case VFT2_UNKNOWN
               FileSubType$ = "Unknown"
         End Select
      Case VFT_FONT
         FileType$ = "Font"
         Select Case X.dwFileSubType
            Case VFT_FONT_RASTER
               FileSubType$ = "Raster Font"
            Case VFT_FONT_VECTOR
               FileSubType$ = "Vector Font"
            Case VFT_FONT_TRUETYPE
               FileSubType$ = "TrueType Font"
         End Select
      Case VFT_VXD
         FileType$ = "VxD"
      Case VFT_STATIC_LIB
         FileType$ = "Lib"
      Case Else
         FileType$ = "Unknown"
   End Select

   Form2.Show 1
End Sub

Sub Drive1_Change ()
   Dir1.Path = Drive1.Drive
   File1.Path = Dir1.Path
   Label1(2).Caption = File1.Path
End Sub

Sub File1_Click ()
   Text1.Text = File1.List(File1.ListIndex)
End Sub

Sub File1_DblClick ()
   DisplayVerInfo
End Sub

Sub File1_PathChange ()
   Text1.Text = "*.*"
   File1.Pattern = "*.*"
End Sub

Sub Form_Load ()
   Dim Buffer$

   ' **** Set Default Dir to Windows System Subdirectory ****
   Buffer$ = Space$(256)
   r% = GetSystemDirectory(Buffer$, Len(Buffer$))
   Dir1.Path = Buffer$
   File1.Path = Buffer$
   Drive1.Drive = Left$(Buffer$, 1)
End Sub

Function HIWORD (X As Long) As Integer
   HIWORD = X \ &HFFFF&
End Function

Function LOWORD (X As Long) As Integer

   LOWORD = X And &HFFFF&
End Function

Sub Text1_KeyPress (KeyAscii As Integer)
   If KeyAscii = 13 Then
      File1.Pattern = Text1.Text
      KeyAscii = 0
      If File1.ListCount = 1 Then DisplayVerInfo
      If File1.ListCount = 0 Then
         MsgBox "Invalid Filename"
         File1.Pattern = "*.*"
         Text1.Text = "*.*"
      End If
      File1.SetFocus
   End If
End Sub

VERINFO2.FRM

' The following is a text dump of the form VERINFO2. It includes the form
' and control description as well as necessary Function and Sub procedures.
' Save the code in a single text file called VERINFO2.FRM and you will
' be able to load it as a form in Visual Basic.
'
VERSION 2.00 Begin Form Form2
   BorderStyle     =   1  'Fixed Single
   Caption         =   "File Version Info"
   ClientHeight    =   3345
   ClientLeft      =   6630
   ClientTop       =   2175
   ClientWidth     =   4500
   FontBold        =   0   'False
   FontItalic      =   0   'False
   FontName        =   "MS Sans Serif"
   FontSize        =   8.25
   FontStrikethru  =   0   'False
   FontUnderline   =   0   'False
   Height          =   3750
   Left            =   6570
   LinkMode        =   1  'Source
   LinkTopic       =   "Form3"
   MaxButton       =   0   'False
   MinButton       =   0   'False
   ScaleHeight     =   13.938
   ScaleMode       =   4  'Character
   ScaleWidth      =   37.5
   Top             =   1830
   Width           =   4620
   Begin CommandButton Command1
      Caption         =   "OK"
      Height          =   372
      Left            =   1680
      TabIndex        =   0
      Top             =   2880
      Width           =   1452
   End
End

Sub Command1_Click ()
   Form2.Hide
End Sub

Sub Command1_GotFocus ()
  Form_Paint
End Sub

Sub Form_Paint ()
   Form2.CurrentX = 2
   Form2.CurrentY = 1
   Form2.Print "FileName:"
   Form2.CurrentX = 2
   Form2.Print "Directory:"
   Form2.CurrentX = 2
   Form2.Print "File Version:"
   Form2.CurrentX = 2
   Form2.Print "Product Version:"
   Form2.CurrentX = 2
   Form2.Print "File Flags:"
   Form2.CurrentX = 2
   Form2.Print "File OS:"
   Form2.CurrentX = 2
   Form2.Print "File Type:"
   Form2.CurrentX = 2
   Form2.Print "File Sub-type:"

   Form2.CurrentX = 18
   Form2.CurrentY = 1
   Form2.Print FileName$
   Form2.CurrentX = 18
   Form2.Print Directory$
   Form2.CurrentX = 18
   Form2.Print FileVer$
   Form2.CurrentX = 18
   Form2.Print ProdVer$
   Form2.CurrentX = 18
   Form2.Print FileFlags$
   Form2.CurrentX = 18
   Form2.Print FileOS$
   Form2.CurrentX = 18
   Form2.Print FileType$
   Form2.CurrentX = 18
   Form2.Print FileSubType$
End Sub

How to Create and Run the Program

  1. Start Visual Basic. Form1 is created by default.

  2. From the File menu, choose Remove File to remove Form1.

  3. From the File menu, choose Add File... to and add VERINFO.BAS

  4. Repeat step 3 to add VERINFO1.FRM and VERINFO2.FRM to the project.

  5. From the Options menu, choose Project... and set Start Up Form to Form1.

  6. Run the application.


Additional reference words: 2.00 3.00 4.00 codesmpl vb416 vb4win
KBCategory: kbprg kbcode kbhowto
KBSubCategory: APrgWindow



THE INFORMATION PROVIDED IN THE MICROSOFT KNOWLEDGE BASE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY KIND. MICROSOFT DISCLAIMS ALL WARRANTIES, EITHER EXPRESS OR IMPLIED, INCLUDING THE WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL MICROSOFT CORPORATION OR ITS SUPPLIERS BE LIABLE FOR ANY DAMAGES WHATSOEVER INCLUDING DIRECT, INDIRECT, INCIDENTAL, CONSEQUENTIAL, LOSS OF BUSINESS PROFITS OR SPECIAL DAMAGES, EVEN IF MICROSOFT CORPORATION OR ITS SUPPLIERS HAVE BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. SOME STATES DO NOT ALLOW THE EXCLUSION OR LIMITATION OF LIABILITY FOR CONSEQUENTIAL OR INCIDENTAL DAMAGES SO THE FOREGOING LIMITATION MAY NOT APPLY.

Last reviewed: May 2, 1996
© 1998 Microsoft Corporation. All rights reserved. Terms of Use.