读取二进制可执行文件资源中包含的各项版本信息


可以读取进制可执行文件资源中包含的各项版本信息的封装类,代码如下:



andlua二进制执行后面失效了 二进制执行文件_版本信息

#pragma once

class CFileVersion
 {
public:
     CFileVersion();
     virtual ~CFileVersion();

public:
     struct STranslateBlockItem
     {
         WORD wLanguage;
         WORD wCodePage;
     };

public:
     // 设置当前使用的语言 ID
    BOOL SetLanguage(LANGID uLangID);

     // 初始化版本信息模块句柄
    BOOL InitVersion(HMODULE hModule = NULL);

     // 初始化版本信息路径名称
    BOOL InitVersion(LPCTSTR lpszImageName);

public:
     // 获取字符串格式的文件创建日期
    static BOOL GetFileDate( LPCTSTR lpszFile , LPTSTR lpStr , UINT nSize );

     // 获取字符串格式的文件大小
    static BOOL GetFileSize( LPCTSTR lpszFile , LPTSTR lpStr , UINT nSize );

     // 获取文件的属性、创建日期、编辑日期、访问日期和大小
    static BOOL GetFileAttr( LPCTSTR lpszFile , LPWIN32_FILE_ATTRIBUTE_DATA lpFileAttr );

public:
     // 获取文件的属性、创建日期、编辑日期、访问日期和大小
    BOOL GetFileAttr( LPWIN32_FILE_ATTRIBUTE_DATA lpFileAttr );

     // 获取字符串格式的文件创建日期
    BOOL GetFileDate(LPTSTR lpStr, UINT nSize);

     // 获取字符串格式的文件创建日期
    BOOL GetFileSize(LPTSTR lpStr, UINT nSize);


public:
     // 获取固定的文件信息
    BOOL GetFixedFileInfo(VS_FIXEDFILEINFO& rFixedInfo);

     // 获取字符串格式的产品版本信息
    BOOL GetProductVersion(LPTSTR lpStr, UINT nSize);

     // 获取字符串格式的文件版本信息
    BOOL GetFileVersion(LPTSTR lpStr, UINT nSize);

     // 获取数字格式的产品版本信息
    BOOL GetProductVersion(WORD wVersion[]);

     // 获取数字格式的文件版本信息
    BOOL GetFileVersion(WORD wVersion[]);

public:
     // 根据字符串参数获得特定信息字符串
    LPCTSTR GetVersionString(LPCTSTR lpStrVersion);

     // 获取特定版本号
    LPCTSTR GetSpecialBuild();    

     // 获取私有版本号
    LPCTSTR GetPrivateBuild();

     // 获取注册商标
    LPCTSTR GetLegalTrademarks();

     // 获取内部名称
    LPCTSTR GetInternalName();

     // 获取文件版本
    LPCTSTR GetFileVersion();

     // 获取文件描述
    LPCTSTR GetFileDescription();

     // 获取注释信息
    LPCTSTR GetComments();

     // 获取版权信息
    LPCTSTR GetCopyright();

     // 获取公司名称
    LPCTSTR GetCompanyName();

     // 获取产品版本
    LPCTSTR GetProductVersion();

     // 获取产品名称
    LPCTSTR GetProductName();

protected:
     // 初始化文件信息块
    BOOL InitFileVersion();

private:
     LPTSTR    m_lpImage;
     
     DWORD    m_dwHandle;
     DWORD    m_dwLangBlock;

     DWORD    m_dwVersionBuffer;
     LPVOID    m_lpVersionBuffer;
     
     UINT    m_nVersion;
     LPVOID  m_lpVersion;

     UINT    m_nTranslate;
     LPVOID  m_lpTranslate;
 };



下面是该封装类的实现代码:



andlua二进制执行后面失效了 二进制执行文件_版本信息

#define _CRT_SECURE_NO_WARNINGS

 #include <windows.h>
 #include "FileVersion.h"

#pragma comment(lib, "version.lib")

 #ifdef UNICODE
#define strcpy wcscpy
#endif

#define MAKETRANSCODE(l,c) ((DWORD)(((l & 0xFFFF) << 16) | (c & 0xFFFF)))
#define MAKETRANSLANG(p) MAKETRANSCODE((p)->wLanguage,(p)->wCodePage)    

 CFileVersion::CFileVersion()
 {
     m_dwVersionBuffer = 0;
     m_lpVersionBuffer = NULL;
     m_lpVersion = NULL;
     m_nVersion = NULL;
     m_dwLangBlock = 0;

     m_dwHandle = NULL;

     m_nTranslate = 0;
     m_lpTranslate = NULL;
 }

 CFileVersion::~CFileVersion()
 {
     if(m_lpVersionBuffer != NULL)
     {
         free(m_lpVersionBuffer);
         m_lpVersionBuffer = NULL;
     }
 }

 BOOL CFileVersion::InitVersion(HMODULE hModule)
 {
     TCHAR szFileName[MAX_PATH] = { TEXT("") };
     GetModuleFileName(hModule,szFileName,MAX_PATH);
     return InitVersion(szFileName);
 }

 BOOL CFileVersion::InitVersion(LPCTSTR lpszImageName)
 {
     static TCHAR szImageName[MAX_PATH] = { TEXT("") };
     strncpy(szImageName, lpszImageName, MAX_PATH);
     m_lpImage = szImageName;

     return InitFileVersion();
 }

 BOOL CFileVersion::InitFileVersion()
 {
     m_dwHandle = 0;
     if(m_lpVersionBuffer != NULL)
     {
         free(m_lpVersionBuffer);
         m_lpVersionBuffer = NULL;
     }

     m_nTranslate = 0;
     m_lpTranslate = NULL;

     // 获取版本信息块的大小,然后申请内存并初始化
    TCHAR szImage[MAX_PATH] = { TEXT("") };
     lstrcpy(szImage,m_lpImage);
     LPTSTR lpszImage = szImage;

     m_dwVersionBuffer = ::GetFileVersionInfoSize(lpszImage, &m_dwHandle);
     if(m_dwVersionBuffer == 0)
     {
         // 该模块没有版本信息
        return false;
     }

     m_dwVersionBuffer += 256;
     m_lpVersionBuffer = malloc(m_dwVersionBuffer); 
     memset(m_lpVersionBuffer,0,m_dwVersionBuffer);

     // 获得文件的版本信息块内容
    ::GetFileVersionInfo(lpszImage, 0, m_dwVersionBuffer, m_lpVersionBuffer);

     // 获取当前所有的语言和代码页
    UINT cbTranslate = 0;
     LPTSTR lpStr = TEXT("\\VarFileInfo\\Translation");
     VerQueryValue(m_lpVersionBuffer, lpStr, (LPVOID*)&m_lpTranslate, &cbTranslate);
     m_nTranslate = cbTranslate / sizeof(STranslateBlockItem);

     // 设置默认的语言
    return SetLanguage(GetUserDefaultLangID());
 }

 BOOL CFileVersion::SetLanguage(LANGID uLangID)
 {
     if(m_lpTranslate == NULL)
     {
         // 没有翻译项
        return false;
     }

     const DWORD dwInvalid = 0xFFFFFFFF;

     DWORD dwSet, dwUser, dwSystem;
     dwSet = dwSystem = dwUser = dwInvalid;
     LANGID uLangUser = GetUserDefaultLangID();
     LANGID uLangSystem = GetSystemDefaultLangID();
     STranslateBlockItem* lpItem = (STranslateBlockItem*)m_lpTranslate;
     for(UINT iCode = 0 ; iCode < m_nTranslate ; iCode ++)
     {
         if(lpItem[iCode].wLanguage == uLangID)
         {
             dwSet = MAKETRANSLANG(lpItem + iCode);
         }
         
         if(lpItem[iCode].wLanguage == uLangUser)
         {
             dwUser = MAKETRANSLANG(lpItem + iCode);
         }

         if(lpItem[iCode].wLanguage == uLangSystem)
         {
             dwSystem = MAKETRANSLANG(lpItem + iCode);
         }
     }

     // 第一个翻译块项目
    DWORD dwFirst = MAKETRANSLANG(lpItem);

     // 等于用户设置的项目
    m_dwLangBlock = dwSet;
     
     // 如果无效,设置为用户默认
    if(m_dwLangBlock == dwInvalid)
     {
         m_dwLangBlock = dwUser;
     }

     // 如果无效,设置为系统默认
    if(m_dwLangBlock == dwInvalid)
     {
         m_dwLangBlock = dwSystem;
     }

     // 如果无效,设置为第一个
    if(m_dwLangBlock == dwInvalid)
     {
         m_dwLangBlock = dwFirst;
     }

     return true;
 }

 BOOL CFileVersion::GetFixedFileInfo(VS_FIXEDFILEINFO& rFixedInfo)
 {
     if(m_lpVersionBuffer != NULL)
     {
         UINT nLength = 0; PVOID lpFixedInfo = NULL;
         if(VerQueryValue(m_lpVersionBuffer,TEXT("\\"),&lpFixedInfo,&nLength))
         {
             memcpy(&rFixedInfo,lpFixedInfo,sizeof(VS_FIXEDFILEINFO));
             return true;
         }
     }
     return false;
 }

 BOOL CFileVersion::GetProductVersion(LPTSTR lpStr, UINT nSize)
 {
     WORD wVersion[4] = {0,0,0,0};
     if(GetProductVersion(wVersion))
     {
         LPWORD ver = wVersion;
         TCHAR szBuffer[1024] = { TEXT("") };
         wsprintf(szBuffer,TEXT("%d.%d.%d.%d"),ver[0],ver[1],ver[2],ver[3]);
         if((lpStr != NULL) && (nSize > (UINT)lstrlen(szBuffer)))
         {
             lstrcpy(lpStr,szBuffer);
             return true;
         }
     }
     return false;
 }

 BOOL CFileVersion::GetFileVersion(LPTSTR lpStr, UINT nSize)
 {
     WORD wVersion[4] = {0,0,0,0};
     if(GetFileVersion(wVersion))
     {
         LPWORD ver = wVersion;
         TCHAR szBuffer[1024] = { TEXT("") };
         wsprintf(szBuffer,TEXT("%d.%d.%d.%d"),ver[0],ver[1],ver[2],ver[3]);
         if((lpStr != NULL) && (nSize > (UINT)lstrlen(szBuffer)))
         {
             lstrcpy(lpStr,szBuffer);
             return true;
         }
     }
     return false;
 }

 BOOL CFileVersion::GetProductVersion(WORD wVersion[])
 {
     VS_FIXEDFILEINFO fixInfo;
     if(!GetFixedFileInfo(fixInfo)) return false;
     wVersion[0] = HIWORD(fixInfo.dwProductVersionMS);
     wVersion[1] = LOWORD(fixInfo.dwProductVersionMS);
     wVersion[2] = HIWORD(fixInfo.dwProductVersionLS);
     wVersion[3] = LOWORD(fixInfo.dwProductVersionLS);
     return true;
 }

 BOOL CFileVersion::GetFileVersion(WORD wVersion[])
 {
     VS_FIXEDFILEINFO fixInfo;
     if(!GetFixedFileInfo(fixInfo)) return false;
     wVersion[0] = HIWORD(fixInfo.dwFileVersionMS);
     wVersion[1] = LOWORD(fixInfo.dwFileVersionMS);
     wVersion[2] = HIWORD(fixInfo.dwFileVersionLS);
     wVersion[3] = LOWORD(fixInfo.dwFileVersionLS);
     return true;
 }

 BOOL CFileVersion::GetFileDate(LPCTSTR lpszFile,LPTSTR lpStr, UINT nSize)
 {
     WIN32_FILE_ATTRIBUTE_DATA xAttr = { 0 };
     if( GetFileAttr( lpszFile , & xAttr ) )
     {
         SYSTEMTIME st = { 0 };
         TCHAR szBuffer[1024] = { TEXT("") };
         FileTimeToSystemTime( & xAttr.ftLastWriteTime, &st );
         TCHAR szFormat[] = { TEXT("%04d-%02d-%02d %02d:%02d:%02d") };
         wsprintf(szBuffer,szFormat,st.wYear,st.wMonth,st.wDay,st.wHour,st.wMinute,st.wSecond);
         if((lpStr != NULL) && (nSize > (UINT)lstrlen(szBuffer)))
         {
             lstrcpy(lpStr,szBuffer);
             return true;
         }
     }
     return false;
 }

 BOOL CFileVersion::GetFileSize(LPCTSTR lpszFile,LPTSTR lpStr, UINT nSize)
 {
     WIN32_FILE_ATTRIBUTE_DATA xAttr = { 0 };
     if( GetFileAttr( lpszFile , & xAttr ) )
     {
         TCHAR szBuffer[1024] = { TEXT("") };
         wsprintf(szBuffer,TEXT("%u"),xAttr.nFileSizeLow);
         if((lpStr != NULL) && (nSize > (UINT)lstrlen(szBuffer)))
         {
             lstrcpy(lpStr,szBuffer);
             return true;
         }
     }
     return false;
 }

 BOOL CFileVersion::GetFileAttr( LPCTSTR lpszFile , LPWIN32_FILE_ATTRIBUTE_DATA lpFileAttr )
 {
     return GetFileAttributesEx( lpszFile , GetFileExInfoStandard , lpFileAttr );
 }

// 获取字符串格式的文件创建日期
BOOL CFileVersion::GetFileDate(LPTSTR lpStr, UINT nSize)
 {
     return GetFileDate(m_lpImage,lpStr,nSize);
 }

// 获取字符串格式的文件创建日期
BOOL CFileVersion::GetFileSize(LPTSTR lpStr, UINT nSize)
 {
     return GetFileSize(m_lpImage,lpStr,nSize);
 }

// 获取文件创建日期
BOOL CFileVersion::GetFileAttr( LPWIN32_FILE_ATTRIBUTE_DATA lpFileAttr )
 {
     return GetFileAttr( m_lpImage , lpFileAttr );
 }

 LPCTSTR CFileVersion::GetVersionString(LPCTSTR lpStrVersion)
 {
     if(m_lpVersionBuffer != NULL)
     {
         TCHAR szBlock[MAX_PATH] = { TEXT("") };
         wsprintf(szBlock,TEXT("\\StringFileInfo\\%08X\\%s"),m_dwLangBlock,lpStrVersion);
         VerQueryValue(m_lpVersionBuffer,(LPTSTR)szBlock,&m_lpVersion,&m_nVersion);
         return (LPCTSTR)m_lpVersion;
     }
     return TEXT("");
 }

 LPCTSTR CFileVersion::GetProductName()
 {
     return GetVersionString(TEXT("ProductName"));
 }

 LPCTSTR CFileVersion::GetProductVersion()
 {
     return GetVersionString(TEXT("ProductVersion"));
 }

 LPCTSTR CFileVersion::GetCompanyName()
 {
     return GetVersionString(TEXT("CompanyName"));
 }

 LPCTSTR CFileVersion::GetCopyright()
 {
     return GetVersionString(TEXT("LegalCopyright"));
 }

 LPCTSTR CFileVersion::GetComments()
 {
     return GetVersionString(TEXT("Comments"));
 }

 LPCTSTR CFileVersion::GetFileDescription()
 {
     return GetVersionString(TEXT("FileDescription"));
 }

 LPCTSTR CFileVersion::GetFileVersion()
 {
     return GetVersionString(TEXT("FileVersion"));
 }

 LPCTSTR CFileVersion::GetInternalName()
 {
     return GetVersionString(TEXT("InternalName"));
 }

 LPCTSTR CFileVersion::GetLegalTrademarks()
 {
     return GetVersionString(TEXT("LegalTrademarks"));
 }

 LPCTSTR CFileVersion::GetPrivateBuild()
 {
     return GetVersionString(TEXT("PrivateBuild"));
 }

 LPCTSTR CFileVersion::GetSpecialBuild()
 {
     return GetVersionString(TEXT("SpecialBuild"));
 }



使用方法示例如下:



andlua二进制执行后面失效了 二进制执行文件_版本信息
   

CFileVersion verFile; 
         if(false == verFile.InitVersion(szModule))
         {
             DumpPrint(hFile, "Version information block not found\n");
             return ERR_FAILURE;
         }

         DumpPrint(hFile, "Product Version   : %s\n",verFile.GetProductVersion());
         DumpPrint(hFile, "Product Name      : %s\n",verFile.GetProductName());

         DumpPrint(hFile, "File Description  : %s\n",verFile.GetFileDescription());
         DumpPrint(hFile, "File Version      : %s\n",verFile.GetFileVersion());

         DumpPrint(hFile, "Company Name      : %s\n",verFile.GetCompanyName());
         DumpPrint(hFile, "Comments          : %s\n",verFile.GetComments());