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
沒有留言:
張貼留言