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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值