CFileVersionInfo - Getting the File Version Information






4.84/5 (50 votes)
Class for getting file version information
Introduction
You can use this class to determine a full file version information, in any file that has 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 aCFileVersionInfo
object
Operations
BOOL Open( IN LPCTSTR lpszFileName )
- Opens the file version information by its name specified inlpszFileName
BOOL Open( IN HMODULE hModule )
- Opens the file version information by its handle specified inhModule
void Close( void )
- Closes the specified module and frees the resources, loaded byOpen
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 aStringTable
structure, and returns it in thenBuf
sizelpszValue
buffer. ThelpszString
name must be one of the predefined strings, enumerated in the next function description. For example:m_ver.QueryStringValue( _T( "Comments" ), szBuf, 512 );
.
NOTE: It is better you 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 aStringTable
structure, and returns it in thenBuf
sizelpszValue
buffer. ThenIndex
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 theVS_FIXEDFILEINFO
structure of the open file version information.LPCTSTR GetVerStringName( IN INT nIndex )
- Returns the version string name for thenIndex
parameter from the array - the class holds astatic
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 versionGetVersionMinor( void ) const
- get minor versionGetVersionBuild( void ) const
- get build versionGetVersionQFE( void ) const
- get QFE version
Static Members
BOOL GetLIDName( IN WORD wLID, OUT LPTSTR lpszName, IN INT nBuf )
- Retrieves a descriptionstring
for thewLID
language identifier and returns it in thelpszName
buffer ofnBuf
size.BOOL GetCPName( IN WORD wCP, OUT LPCTSTR* ppszName )
- Retrieves a descriptionstring
for thewCP
code page identifier and returns it in thelpszName
buffer ofnBuf
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 version information data, if anyBOOL 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 exportedDllGetVersion
of any of your DLLs to do the black work - return the pointer toDLLVERSIONINFO
structure filled with your app version data. It uses theCFileVersionInfo
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
- 15th July, 2003
- Posted article
- 27th July, 2003
- Removed
VOS_DOS_WINDOWS32
fromDllGetVersion
file type detection - Updated
DllGetVersion
to supportDLLVERSIONINFO2
structure
- Removed
- 21st January, 2004
- Added
GetFileVersionMajor
,GetFileVersionMinor
,GetFileVersionBuild
,GetFileVersionQFE
functions
- Added
- 29th March, 2004
- Added
GetProductVersionMajor
,GetProductVersionMinor
,GetProductVersionBuild
,GetProductVersionQFE
functions
- Added