C++ 如何读取文件的版本信息

    xiaoxiao2023-03-24  5

    C++ 如何读取文件的版本信息 有些时候,我们需要知道程序调用的库或者某个exe文件的版本信息(或其他相关属性信息时)。这时就需要考虑到如何去读取这些文件的版本信息呢?     从万能的网上查到了VerQueryValue函数,可以实现我们的需求。 说明:在使用VerQueryValue函数之前,必须先使用GetFileVersionInfoSize和GetFileVersionInfo这两个函数。 1.函数说明 /* Returns size of version info in bytes */ DWORD APIENTRY GetFileVersionInfoSizeA(     __in LPCSTR lptstrFilename, /* Filename of version stamped file */     __out_opt LPDWORD lpdwHandle     );                      /* Information for use by GetFileVersionInfo */ /* Read version info into buffer */ BOOL APIENTRY GetFileVersionInfoA(     __in LPCSTR lptstrFilename, /* Filename of version stamped file */     __in DWORD dwHandle,         /* Information from GetFileVersionSize */     __in DWORD dwLen,            /* Length of buffer for info */     __out_bcount(dwLen) LPVOID lpData     );                      /* Buffer to place the data structure */ BOOL APIENTRY VerQueryValueA(         const LPVOID pBlock,         LPSTR lpSubBlock,         LPVOID * lplpBuffer,         PUINT puLen         ); 2.程序实例 2.1要包含#pragma comment(lib,"version.lib")这个库文件 2.2 这里封装好了函数,如下: bool QueryValue(const std::string& ValueName, const std::string& szModuleName, std::string& RetStr)   {       bool bSuccess = FALSE;       BYTE*  m_lpVersionData = NULL;       DWORD   m_dwLangCharset = 0;       CHAR *tmpstr = NULL;       do       {           if (!ValueName.size() || !szModuleName.size())               break;           DWORD dwHandle;           // 判断系统能否检索到指定文件的版本信息   //针对包含了版本资源的一个文件,判断容纳 文件版本信息需要一个多大的缓冲区 //返回值说明Long,容纳文件的版本资源所需的缓冲区长度。如文件不包含版本信息,则返回一个0值。会设置GetLastError参数表         DWORD dwDataSize = ::GetFileVersionInfoSizeA((LPCSTR)szModuleName.c_str(), &dwHandle);           if (dwDataSize == 0)               break;   //std::nothrow:在内存不足时,new (std::nothrow)并不抛出异常,而是将指针置NULL。         m_lpVersionData = new (std::nothrow) BYTE[dwDataSize];// 分配缓冲区           if ( NULL == m_lpVersionData)               break;           // 检索信息   //从支持版本标记的一个模块里获取文件版本信息         if (!::GetFileVersionInfoA((LPCSTR)szModuleName.c_str(), dwHandle, dwDataSize,               (void*)m_lpVersionData))               break;           UINT nQuerySize;           DWORD* pTransTable;           // 设置语言   //https://msdn.microsoft.com/zh-cn/vstudio/aa909243         if (!::VerQueryValueA(m_lpVersionData, "\\VarFileInfo\\Translation", (void **)&pTransTable, &nQuerySize))               break;   //MAKELONG 将两个16位的数联合成一个无符号的32位数         m_dwLangCharset = MAKELONG(HIWORD(pTransTable[0]), LOWORD(pTransTable[0]));           if (m_lpVersionData == NULL)               break;           tmpstr = new (std::nothrow) CHAR[128];// 分配缓冲区           if (NULL == tmpstr)               break;           sprintf_s(tmpstr, 128, "\\StringFileInfo\\%08lx\\%s", m_dwLangCharset, ValueName.c_str());           LPVOID lpData;           // 调用此函数查询前需要先依次调用函数GetFileVersionInfoSize和GetFileVersionInfo           if (::VerQueryValueA((void *)m_lpVersionData, tmpstr, &lpData, &nQuerySize))               RetStr = (char*)lpData;           bSuccess = TRUE;       } while (FALSE);       // 销毁缓冲区       if (m_lpVersionData)       {           delete[] m_lpVersionData;           m_lpVersionData = NULL;       }       if (tmpstr)       {           delete[] tmpstr;           tmpstr = NULL;       }       return bSuccess;   }   2.3进一步封装读取各个属性信息的函数接口 bool   GetFileDescription(const std::string& szModuleName, std::string& RetStr)   { return QueryValue("FileDescription", szModuleName, RetStr); };   //获取文件说明   bool   GetFileVersion(const std::string& szModuleName, std::string& RetStr)       { return QueryValue("FileVersion", szModuleName, RetStr); };       //获取文件版本    bool   GetInternalName(const std::string& szModuleName, std::string& RetStr)       { return QueryValue("InternalName", szModuleName, RetStr); };      //获取内部名称   bool   GetCompanyName(const std::string& szModuleName, std::string& RetStr)       { return QueryValue("CompanyName", szModuleName, RetStr); };       //获取公司名称   bool   GetLegalCopyright(const std::string& szModuleName, std::string& RetStr)         { return QueryValue("LegalCopyright", szModuleName, RetStr); };    //获取版权   bool   GetOriginalFilename(const std::string& szModuleName, std::string& RetStr)   { return QueryValue("OriginalFilename", szModuleName, RetStr); };  //获取原始文件名   bool   GetProductName(const std::string& szModuleName, std::string& RetStr)        { return QueryValue("ProductName", szModuleName, RetStr); };       //获取产品名称   bool   GetProductVersion(const std::string& szModuleName, std::string& RetStr)         { return QueryValue("ProductVersion", szModuleName, RetStr); };    //获取产品版本   2.4调用读取版本信息 GetFileVersion("xxxxxx.dll",strout);     然后strout就是你想要的版本信息了,如何xxxxx.dll没有改文件或没有版本信息,则strout返回的是空
    转载请注明原文地址: https://ju.6miu.com/read-1201618.html
    最新回复(0)