Click here to Skip to main content
Click here to Skip to main content

CFileVersionInfo - Getting the file version information

, 29 Mar 2004 CPOL
Rate this:
Please Sign up or sign in to vote.
Class for getting file version information

Introduction

You can use this class to determine a full file version information, in any file that have version information resource, such as dynamic-link libraries (DLLs), executable files, font files, OCX files, etc., including version information blocks in multiple languages. This class wraps the GetFileVersionInfo, GetFileVersionInfoSize, VerQueryValue, and VerLanguageName API functions. See sample image below:

Background

Once developing a DLL file, I wanted to implement DllGetVersion function in it (it returns the version of the DLL, if requested, see Platform SDK). Of course I could return fixed version numbers from my implementation of it, but in that case they would become wrong even after a single rebuild (I used version auto increment in that project). So I decided to use the API version information functions - i.e. read version information from the file version information resource and return it every time it was requested - and implemented CFileVersionInfo class.

Sample usage

In this sample we query the Shell32.dll version information (we'll get something in this format: "6.0.2600.0") and its company name string (we'll get something like "Microsoft Corporation"):

//...
#ifndef __VERINFO_H__
    #include < verinfo.h >
#endif
//...

CFileVersionInfo fvi;
if( fvi.Open( _T( "shell32.dll" ) )
{
    TCHAR szVer[ 512 ] = { 0 };
    ::wsprintf( szVer, 
        _T( "%d.%d.%d.%d" ),
        fvi.GetFileVersionMajor(),  // Major version
        fvi.GetFileVersionMinor(),  // Minor version
        fvi.GetFileVersionBuild(),  // Build number
        fvi.GetFileVersionQFE()     // QFE
    );

    /*
    VS_FIXEDFILEINFO vsffi = m_fvi.GetVSFFI();
    ::wsprintf( szVer, 
        _T( "%d.%d.%d.%d" ),
        HIWORD( vsffi.dwFileVersionMS ),  // Major version
        LOWORD( vsffi.dwFileVersionMS ),  // Minor version
        HIWORD( vsffi.dwFileVersionLS ),  // Build number
        LOWORD( vsffi.dwFileVersionLS )   // QFE
    );
    */
    
    ::SetWindowText( hWndVersion, szVer );

    if( fvi.QueryStringValue( VI_STR_COMPANYNAME, szVer, 512 ) )
        ::SetWindowText( hWndCompName, szVer );

//...

    fvi.Close();
}
//...

Translation support

If application or DLL supports a list of languages (multi-language version info blocks), instead of using multiple version resources (for each language), you can use this class to get data from them separately, depending on the language identifier and code page:

In the sample application three different language and code page string table version blocks are provided, you can test them all. See the image before selection (above) and after it (below):

Class members

Base Class

  • Does not have a base class

Construction

  • CFileVersionInfo( void ) - Constructs a CFileVersionInfo object:

Operations

  • BOOL Open( IN LPCTSTR lpszFileName ) - Opens the file version information by its name specified in lpszFileName.
  • BOOL Open( IN HMODULE hModule )- Opens the file version information by its handle specified in hModule.
  • void Close( void ) - Closes the specified module and frees the resources, loaded by Open method(s).
  • BOOL IsValid( void ) - Queries, whether the class internal data is valid.

Version information retrieval

  • BOOL QueryStringValue( IN LPCTSTR lpszString, OUT LPTSTR lpszValue, IN INT nBuf ) const - Retrieves a value in a StringTable structure, and returns it in the nBuf size lpszValue buffer. The lpszString name must be one of the predefined strings, enumerated in the next function description. For example: m_ver.QueryStringValue( _T( "Comments" ), szBuf, 512 );. NOTE: You should better use the second version of this function, explained below.
  • BOOL QueryStringValue( IN INT nIndex, OUT LPTSTR lpszValue, IN INT nBuf ) const - Retrieves a value in a StringTable structure, and returns it in the nBuf size lpszValue buffer. The nIndex name must be one of the following predefined constants:
    • VI_STR_COMMENTS - Comments
    • VI_STR_COMPANYNAME - CompanyName
    • VI_STR_FILEDESCRIPTION - FileDescription
    • VI_STR_FILEVERSION - FileVersion
    • VI_STR_INTERNALNAME - InternalName
    • VI_STR_LEGALCOPYRIGHT - LegalCopyright
    • VI_STR_LEGALTRADEMARKS - LegalTrademarks
    • VI_STR_ORIGINALFILENAME - OriginalFilename
    • VI_STR_PRIVATEBUILD - PrivateBuild
    • VI_STR_PRODUCTNAME - ProductName
    • VI_STR_PRODUCTVERSION - ProductVersion
    • VI_STR_SPECIALBUILD - SpecialBuild
    • VI_STR_OLESELFREGISTER - OLESelfRegister

    For example: m_ver.QueryStringValue( VI_STR_SPECIALBUILD, szBuf, 512 );

  • const VS_FIXEDFILEINFO& GetVSFFI( void ) const - Retrieves the reference to the VS_FIXEDFILEINFO structure of the open file version information.
  • LPCTSTR GetVerStringName( IN INT nIndex ) - Returns the version string name for the nIndex parameter from the array - the class holds a static array of version information strings, each value of which can be accessed by index. For example: m_ver.GetVerStringName( VI_STR_PRODUCTNAME )will return a pointer to _T( "ProductName" ) string.
  • GetVersionMajor( void ) const -get major version.
  • GetVersionMinor( void ) const-get minor version.
  • GetVersionBuild( void ) const-get build version.
  • GetVersionQFE( void ) const-get QFE version.

Static members

  • BOOL GetLIDName( IN WORD wLID, OUT LPTSTR lpszName, IN INT nBuf ) - Retrieves a description string for the wLID language identifier and returns it in the lpszName buffer of nBuf size.
  • BOOL GetCPName( IN WORD wCP, OUT LPCTSTR* ppszName ) - Retrieves a description string for the wCP code page identifier and returns it in the lpszName buffer of nBuf size.

Translation methods

  • BOOL SetTrans ( IN LANGID wLID /*= LANG_NEUTRAL*/, IN WORD wCP /*= VI_CP_UNICODE*/ ) - Sets the Language Identifier and Code Page to use in the version information data (if any).
  • INT FindTrans( IN LANGID wLID, IN WORD wCP ) const - Finds the translation (the Language Identifier and Code Page) in the the version information data, if any.
  • BOOL SetTransIndex( IN UINT nIndex /*= 0*/ ) - Sets the translation to use in the version information data by index (if any).
  • DWORD GetTransByIndex( IN UINT nIndex ) const - Extracts the translation (the Language Identifier and Code Page) at the specified index in the translation array (if any).

Inline translation methods

  • UINT GetTransCount( void ) const - Returns the number of translations, i.e. number of concatenations of a language and code page identifies pairs found in the translation array for the resource.
  • UINT GetCurTransIndex( void ) const - Returns the current index of the translation index in the translation array of the version resource.
  • LANGID GetLIDByIndex( IN UINT nIndex ) const - Extracts the Language Identifier from the langid-codepage translation pair at the specified index in the array (if any).
  • WORD GetCPByIndex( IN UINT nIndex ) const - Extracts the Code Page identifier from the langid-codepage translation pair at the specified index in the array (if any).
  • DWORD GetCurTrans( void ) const - Returns the langid-codepage translation pair currently set as default in the class.
  • LANGID GetCurLID( void ) const - Returns the Language Identifier currently set as default in the class.
  • WORD GetCurCP( void ) const - Returns the Code Page currently set as default in the class.

Global functions

STDAPI_( HRESULT ) DllGetVersion( IN HMODULE hModule, OUT DLLVERSIONINFO* lpDVI ) - You can use this function in the exported DllGetVersion of any of your DLLs to do the black work - return the pointer to DLLVERSIONINFO structure filled with your app version data. It uses the CFileVersionInfo class. See its implementation:

//...
#ifndef __VERINFO_H__
    #include < verinfo.h >
#endif
//...

HRESULT STDAPICALLTYPE DllGetVersion( IN  HMODULE hModule, 
                                      OUT DLLVERSIONINFO* lpDVI )
{
    if( hModule == NULL || 
        ::IsBadReadPtr( lpDVI, sizeof( DLLVERSIONINFO* ) ) )
    {
        ASSERT_RETURN( S_FALSE );
    }
    
    const DWORD cbSize = lpDVI->cbSize;
    
    if(
#ifdef DLLVERSIONINFO2
        (
#endif
        cbSize != sizeof( DLLVERSIONINFO  )
#ifdef DLLVERSIONINFO2
        && cbSize != sizeof( DLLVERSIONINFO2 ) ) 
#endif
        || ::IsBadWritePtr( lpDVI, cbSize ) )
    {
        ASSERT_RETURN( S_FALSE );
    }
    
    ::ZeroMemory( lpDVI, cbSize );
    lpDVI->cbSize = cbSize;
    
    CFileVersionInfo fvi;
    if( fvi.Open( hModule ) )
    {
        VS_FIXEDFILEINFO vsffi = fvi.GetVSFFI();
    
        if( vsffi.dwFileType == VFT_DLL ||
            vsffi.dwFileType == VFT_STATIC_LIB )
        {
            switch( vsffi.dwFileOS )
            {            
            case VOS__WINDOWS32:
            case VOS_NT_WINDOWS32:
                lpDVI->dwPlatformID = DLLVER_PLATFORM_WINDOWS;
                break;
            case VOS_NT:
                lpDVI->dwPlatformID = DLLVER_PLATFORM_NT;
                break;            
            default:
                return ( S_FALSE );
            }
    
            lpDVI->dwMajorVersion = HIWORD( vsffi.dwFileVersionMS );
            lpDVI->dwMinorVersion = LOWORD( vsffi.dwFileVersionMS );
            lpDVI->dwBuildNumber  = HIWORD( vsffi.dwFileVersionLS );
    
        #ifdef DLLVERSIONINFO2

            if( cbSize == sizeof( DLLVERSIONINFO2 ) )
            {
                DLLVERSIONINFO2* lpDVI2 = (DLLVERSIONINFO2*)lpDVI;
                lpDVI2->ullVersion = MAKEDLLVERULL( 
                    lpDVI->dwMajorVersion,
                    lpDVI->dwMinorVersion,
                    lpDVI->dwBuildNumber ,
                    LOWORD( vsffi.dwFileVersionLS )
                );
            }
    
        #endif
    
            return ( S_OK );
        }
    #ifdef _DEBUG
        else
            ASSERT( 0 );
    #endif
    
        fvi.Close();
    }
    
    return ( S_FALSE );
}

//...

Notes

This class is a generic class - you can include it in any type of project - in MFC/ATL/WTL/API exe or DLL or some other type applications, it has no dependencies. It compiles with both ANSI and UNICODE at warning level 4.

History

  • 15 Jul 2003
    - Posted the article.
  • 27 Jul 2003
    - Removed VOS_DOS_WINDOWS32 from DllGetVersion file type detection.
    - Updated DllGetVersion to support DLLVERSIONINFO2 structure.
  • 21 Jan 2004
    - Added GetFileVersionMajor, GetFileVersionMinor, GetFileVersionBuild, GetFileVersionQFE functions
  • 29 March 2004
    - Added GetProductVersionMajor, GetProductVersionMinor, GetProductVersionBuild, GetProductVersionQFE functions

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

Share

About the Author

Armen Hakobyan
Software Developer (Senior) SafeNet Inc
United States United States
No Biography provided

Comments and Discussions

 
Bugcan not work for some file Pinmemberxk8888888823-Jun-12 23:31 
GeneralThanks Pinmemberdennislx10-Aug-10 12:53 
GeneralThanks Pinmemberwiccaan30-Oct-07 1:03 
Generalthanks PinmemberLe Thanh Cong16-Apr-06 23:53 
Generalthank you Pinmembermsanchezv30-Jan-06 2:19 
Generalthanks! PinmemberOhad Redlich16-Jan-06 0:57 
GeneralLoading ALL strings from my stringtable PinmemberAlex Evans4-May-05 16:04 
GeneralRe: Loading ALL strings from my stringtable PinmemberArmen Hakobyan5-May-05 20:31 
GeneralRe: Loading ALL strings from my stringtable Pinmembermmatitya12-Sep-06 5:16 
GeneralRe: Loading ALL strings from my stringtable Pinmemberm.vinod8511-Jan-10 8:06 
GeneralRe: Loading ALL strings from my stringtable PinmemberArmen Hakobyan13-Jan-10 4:52 
Generalread file attribute Pinmembersoccers30-Dec-04 19:57 
GeneralRe: read file attribute PinmemberArmen Hakobyan3-Jan-05 22:23 
GeneralRe: read file attribute Pinmembergermanrose23-Aug-06 0:47 
Generalgreat code PinmemberOleg Bykov25-Nov-03 0:02 
GeneralNot very pratical PinmemberXiaotian Guo29-Aug-03 22:08 
GeneralRe: Not very pratical PinmemberArmen Hakobyan30-Aug-03 2:01 
GeneralRe: Not very pratical PinmemberDheht4-Dec-03 13:28 
GeneralRe: Not very pratical Pinmembervirtually_void5-Mar-04 8:14 
GeneralRe: Not very pratical PinmemberClevedon_Peanut8-Apr-04 10:41 
GeneralRe: Not very pratical AT ALL [modified] PinmemberDennisWood4-Jul-06 13:55 
GeneralRe: Not very pratical AT ALL PinmemberFS345984395810-Sep-06 8:08 
Generalconst_cast -&gt; dangerous (crashes?) PinmemberKarl98025-Aug-03 2:07 
GeneralNice! PinmemberRobert Buldoc25-Jul-03 10:08 
GeneralVERY Nice! Pinmembersnyp26-Jul-03 4:22 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Terms of Use | Mobile
Web02 | 2.8.141220.1 | Last Updated 30 Mar 2004
Article Copyright 2003 by Armen Hakobyan
Everything else Copyright © CodeProject, 1999-2014
Layout: fixed | fluid