《Windows API巡礼》---GetFileVersionInfo函数和VerQueryValue函数

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函数用于从指定的版本信息源获取版本信息,在调用该函数之前,需要先依次调用函数GetFileVersionInfoSizeGetFileVersionInfo

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; }

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值