VS_FIXEDFILEINFO 結構包含了文件的版本信息: typedef struct tagVS_FIXEDFILEINFO { DWORD dwSignature; //包含的值是0xFEEF04BD DWORD dwStrucVersion; //該結構的32位二進製版本號,高16位是主版本號,低16位是副版本號 DWORD dwFileVersionMS; //該文件二進製版本號的高32bits DWORD dwFileVersionLS; //該文件二進製版本號的低32bits DWORD dwProductVersionMS; //發布該文件的產品二進製版本號高32bits DWORD dwProductVersionLS; //發布該文件的產品二進製版本號低32bits DWORD dwFileFlagsMask; //比特掩碼,標誌dwFileFlags的有效位 DWORD dwFileFlags; //VS_FF_DEBUG---該文件包含調試信息或是由調試版編譯的 //VS_FF_INFOINFERRED---文件的版本結構是動態創建的, //因此,該結構中有的成員是空的或不正確的 //VS_FF_PATCHED---該文件被修改過 //VS_FF_PRERELEASE---該文件是開發版,不是商業發布版 //VS_FF_PRIVATEBUILD---該文件不是由標準發布步驟構建的 //VS_FF_SPECIALBUILD---該文件是由標準發布步驟構建的, //但是相同版本號文件的變種 DWORD dwFileOS; //該文件設計用於的操作系統 DWORD dwFileType; //文件類型:VFT_APP---文件包含一個應用程序 VFT_DLL---文件包含一個DLL VFT_DRV---文件包含一個設備驅動 VFT_FONT---文件包含一個字體文件 VFT_STATIC_LIB---文件包含一個靜態鏈接庫 VFT_UNKNOWN---文件類型未知 VFT_VXD---文件包含一個虛擬設備 DWORD dwFileSubtype; //文件的子類型,由dwFileType決定 DWORD dwFileDateMS; //二進製文件創建日期和時間戳的高32bits DWORD dwFileDateLS; //二進製文件創建日期和時間戳的低32bits } VS_FIXEDFILEINFO;GetFileVersionInfoSize 函數用於判斷系統能否檢索到指定文件的版本信息,如果可以,函數返回版本信息的字節大小:
DWORD WINAPI GetFileVersionInfoSize( __in LPCTSTR lptstrFilename, //指定文件的名稱 __out_opt LPDWORD lpdwHandle //一個變量的指針,該函數將該變量設為0 );GetFileVersionInfo 函數用來獲得指定文件的版本信息:
BOOL WINAPI GetFileVersionInfo( __in LPCTSTR lptstrFilename, //文件名 __reserved DWORD dwHandle, //保留值 __in DWORD dwLen, //lpData指向緩衝區的大小,使用函數GetFileVersionInfoSize得到 __out LPVOID lpData //指向存放文件版本信息的緩衝區的指針 );VerQueryValue 函數用於從指定的版本信息源獲取版本信息,在調用該函數之前,需要先依次調用函數GetFileVersionInfoSize和GetFileVersionInfo:
BOOL WINAPI VerQueryValue( __in LPCVOID pBlock, //由函數GetFileVersionInfo得到的版本信息源 __in LPCTSTR lpSubBlock, //“/”表示該函數獲取VS_FIXEDFILEINFO結構信息 //為“/VarFileInfo/Translation”表示該函數獲取文件的翻譯表 //為“/StringFileInfo/lang-codepage/string-name”表示該函數獲取文件的字符串信息 __out LPVOID *lplpBuffer, //返回指向pBlock指向的地址,當pBlock被釋放時,該參數也被釋放 __out PUINT puLen //lplpBuffer指向的數據的字節大小 );上面參數lpSubBlock取值中的string-name必須是下面系統預定義的字符串之一: 下面代碼實例封裝了一個文件版本信息類,使用上面介紹的函數方便地獲取文件版本信息,頭文件定義如下FileVersion.h:
// FileVersion.h: interface for the CFileVersion class. // by Manuel Laflamme ////////////////////////////////////////////////// //////////////////// #ifndef __FILEVERSION_H_ #define __FILEVERSION_H_ #if _MSC_VER >= 1000 #pragma once #endif // _MSC_VER >= 1000 class CFileVersion { // Construction public : CFileVersion(); // Operations public : BOOL Open( LPCTSTR lpszModuleName); void Close(); CString QueryValue( LPCTSTR lpszValueName, DWORD dwLangCharset = 0); CString GetFileDescription() { return QueryValue(_T( "FileDescription" )); }; CString GetFileVersion() { return QueryValue(_T( "FileVersion" )); }; CString GetInternalName() { return QueryValue(_T( "InternalName" )); }; CString GetCompanyName() { return QueryValue(_T( "CompanyName" )); }; CString GetLegalCopyright() { return QueryValue(_T( "LegalCopyright" )); }; CString GetOriginalFilename() { return QueryValue(_T( "OriginalFilename" ));}; CString GetProductName() { return QueryValue(_T( "ProductName" )); }; CString GetProductVersion() { return QueryValue(_T( "ProductVersion" )); }; BOOL GetFixedInfo(VS_FIXEDFILEINFO& vsffi); CString GetFixedFileVersion(); CString GetFixedProductVersion(); // Attributes protected : LPBYTE m_lpVersionData; DWORD m_dwLangCharset; // Implementation public : ~CFileVersion(); }; #endif // __FILEVERSION_H_頭文件的實現如下FileVersion.cpp:
// FileVersion.cpp: implementation of the CFileVersion class. // by Manuel Laflamme ////////////////////////////////////////////////// //////////////////// #include "FileVersion.h" #pragma comment(lib, "version") #ifdef _DEBUG #undef THIS_FILE static char THIS_FILE[]=__FILE__; #define new DEBUG_NEW #endif ////////////////////////////////////////////////// //////////////////// CFileVersion::CFileVersion() { m_lpVersionData = NULL; m_dwLangCharset = 0; } CFileVersion::~CFileVersion() { Close(); } void CFileVersion::Close() { delete [] m_lpVersionData; m_lpVersionData = NULL; m_dwLangCharset = 0; } BOOL CFileVersion::Open( LPCTSTR lpszModuleName) { ASSERT(_tcslen(lpszModuleName) > 0); ASSERT(m_lpVersionData == NULL); // Get the version information size for allocate the buffer DWORD dwHandle; DWORD dwDataSize = ::GetFileVersionInfoSize(( LPTSTR )lpszModuleName, &dwHandle); if ( dwDataSize == 0 ) return FALSE; // Allocate buffer and retrieve version information m_lpVersionData = new BYTE [dwDataSize]; if (!::GetFileVersionInfo(( LPTSTR )lpszModuleName, dwHandle, dwDataSize, ( void **)m_lpVersionData) ) { Close(); return FALSE; } // Retrieve the first language and character-set identifier UINT nQuerySize; DWORD * pTransTable; if (!::VerQueryValue(m_lpVersionData, _T( "//VarFileInfo//Translation" ), ( void **)&pTransTable, &nQuerySize) ) { Close(); return FALSE; } // Swap the words to have lang-charset in the correct format m_dwLangCharset = MAKELONG(HIWORD(pTransTable[0]), LOWORD(pTransTable[0])); return TRUE; } CString CFileVersion::QueryValue( LPCTSTR lpszValueName, DWORD dwLangCharset /* = 0*/ ) { // Must call Open() first ASSERT(m_lpVersionData != NULL); if ( m_lpVersionData == NULL ) return (CString)_T( "" ); // If no lang-charset specified use default if ( dwLangCharset == 0 ) dwLangCharset = m_dwLangCharset; // Query version information value UINT nQuerySize; LPVOID lpData; CString strValue, strBlockName; strBlockName.Format(_T( "//StringFileInfo//%08lx//%s" ), dwLangCharset, lpszValueName); if ( ::VerQueryValue(( void **)m_lpVersionData, strBlockName.GetBuffer(0), &lpData, &nQuerySize) ) strValue = ( LPCTSTR )lpData; strBlockName.ReleaseBuffer(); return strValue; } BOOL CFileVersion::GetFixedInfo(VS_FIXEDFILEINFO& vsffi) { // Must call Open() first ASSERT(m_lpVersionData != NULL); if ( m_lpVersionData == NULL ) return FALSE; UINT nQuerySize; VS_FIXEDFILEINFO* pVsffi; if ( ::VerQueryValue(( void **)m_lpVersionData, _T( "//" ), ( void **)&pVsffi, &nQuerySize) ) { vsffi = *pVsffi; return TRUE; } return FALSE; } CString CFileVersion::GetFixedFileVersion() { CString strVersion; VS_FIXEDFILEINFO vsffi; if ( GetFixedInfo(vsffi) ) { strVersion.Format (_T( "%u,%u,%u,%u" ),HIWORD(vsffi.dwFileVersionMS), LOWORD(vsffi.dwFileVersionMS), HIWORD(vsffi.dwFileVersionLS), LOWORD(vsffi.dwFileVersionLS)); } return strVersion; } CString CFileVersion::GetFixedProductVersion() { CString strVersion; VS_FIXEDFILEINFO vsffi; if ( GetFixedInfo(vsffi) ) { strVersion.Format (_T( "%u,%u,%u,%u" ), HIWORD(vsffi.dwProductVersionMS), LOWORD(vsffi.dwProductVersionMS), HIWORD(vsffi.dwProductVersionLS), LOWORD(vsffi.dwProductVersionLS)); } return strVersion; }
資料來源: http://blog.csdn.net/ace1985/article/details/5732024
沒有留言:
張貼留言