(5条消息) 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

(0)

相关推荐