一、需求背景
获取软件下依赖的dll库的版本信息,如下图所示版本为1.0.7.1018
二、实现方法
2.1步骤
windows下实现,基于version.lib(version.dll)提供的函数获取这些信息
首先使用GetFileVersionInfoSizeA(W)获取VersionInfo的大小,申请缓冲区;
接着使用GetFileVersionInfoA(W)获取VersionInfo数据到缓冲区;
接着使用VerQueryValueA(W)依次获取\,\VarFileInfo\Translation,再根据Translation获取语言类型,接着\VarFileInfo\080404B0\ProductVersion便获取到了版本信息。
参考:https://www.cnblogs.com/comor/p/10607383.html
2.2 源码
#include <QDebug>
#include <string>
#include <tchar.h>
#include <iostream>
#include <windows.h>
BOOL GetFileInfoStringWinApi(LPCTSTR pFileName, LPCTSTR pName /* = NULL */, LPTSTR ptBuf, UINT lenBuf)
{
DWORD dwDummyHandle = 0; // will always be set to zero
DWORD dwLen = 0;
BYTE *pVersionInfo = NULL;
BOOL bRetVal;
VS_FIXEDFILEINFO FileVersion;
HMODULE hVerDll;
hVerDll = LoadLibrary(_T("VERSION.dll"));
if (hVerDll == NULL)
{
return FALSE;
}
#ifdef _UNICODE
typedef DWORD(WINAPI * Fun_GetFileVersionInfoSize)(LPCTSTR, DWORD *);
typedef BOOL(WINAPI * Fun_GetFileVersionInfo)(LPCTSTR, DWORD, DWORD, LPVOID);
typedef BOOL(WINAPI * Fun_VerQueryValue)(LPCVOID, LPCTSTR, LPVOID, PUINT);
#else
typedef DWORD(WINAPI * Fun_GetFileVersionInfoSize)(LPCSTR, DWORD *);
typedef BOOL(WINAPI * Fun_GetFileVersionInfo)(LPCSTR, DWORD, DWORD, LPVOID);
typedef BOOL(WINAPI * Fun_VerQueryValue)(LPCVOID, LPCSTR, LPVOID, PUINT);
#endif
Fun_GetFileVersionInfoSize pGetFileVersionInfoSize;
Fun_GetFileVersionInfo pGetFileVersionInfo;
Fun_VerQueryValue pVerQueryValue;
#ifdef _UNICODE
pGetFileVersionInfoSize = (Fun_GetFileVersionInfoSize)::GetProcAddress(hVerDll, "GetFileVersionInfoSizeW");
pGetFileVersionInfo = (Fun_GetFileVersionInfo)::GetProcAddress(hVerDll, "GetFileVersionInfoW");
pVerQueryValue = (Fun_VerQueryValue)::GetProcAddress(hVerDll, "VerQueryValueW");
#else
pGetFileVersionInfoSize = (Fun_GetFileVersionInfoSize)::GetProcAddress(hVerDll, "GetFileVersionInfoSizeA");
pGetFileVersionInfo = (Fun_GetFileVersionInfo)::GetProcAddress(hVerDll, "GetFileVersionInfoA");
pVerQueryValue = (Fun_VerQueryValue)::GetProcAddress(hVerDll, "VerQueryValueA");
#endif
struct TRANSLATION
{
WORD langID; // language ID
WORD charset; // character set (code page)
} Translation;
Translation.langID = 0x0409; //
Translation.charset = 1252; // default = ANSI code page
dwLen = pGetFileVersionInfoSize(pFileName, &dwDummyHandle);
if (dwLen == 0)
{
bRetVal = FALSE;
goto End;
}
pVersionInfo = new BYTE[dwLen]; // allocate version info
bRetVal = pGetFileVersionInfo(pFileName, 0, dwLen, pVersionInfo);
if (bRetVal == FALSE)
{
goto End;
}
VOID *pVI;
UINT uLen;
bRetVal = pVerQueryValue(pVersionInfo, _T("\\"), &pVI, &uLen);
if (bRetVal == FALSE)
{
goto End;
}
memcpy(&FileVersion, pVI, sizeof(VS_FIXEDFILEINFO));
bRetVal = pVerQueryValue(pVersionInfo, _T("\\VarFileInfo\\Translation"),
&pVI, &uLen);
if (bRetVal && uLen >= 4)
{
memcpy(&Translation, pVI, sizeof(TRANSLATION));
}
else
{
bRetVal = FALSE;
goto End;
}
// BREAKIF(FileVersion.dwSignature != VS_FFI_SIGNATURE);
if (FileVersion.dwSignature != VS_FFI_SIGNATURE)
{
bRetVal = FALSE;
goto End;
}
VOID *pVal;
UINT iLenVal;
if (pName == NULL)
{
_stprintf_s(ptBuf, lenBuf, _T("%d.%d.%d.%d"),
HIWORD(FileVersion.dwFileVersionMS), LOWORD(FileVersion.dwFileVersionMS),
HIWORD(FileVersion.dwFileVersionLS), LOWORD(FileVersion.dwFileVersionLS));
}
else
{
TCHAR szQuery[1024];
_stprintf_s(szQuery, 1024, _T("\\StringFileInfo\\%04X%04X\\%s"),
Translation.langID, Translation.charset, pName);
bRetVal = pVerQueryValue(pVersionInfo, szQuery, &pVal, &iLenVal);
if (bRetVal)
{
_stprintf_s(ptBuf, lenBuf, _T("%s"), (TCHAR *)pVal);
}
else
{
_stprintf_s(ptBuf, lenBuf, _T("%s"), _T(""));
}
}
End:
FreeLibrary(hVerDll);
hVerDll = NULL;
delete[] pVersionInfo;
pVersionInfo = NULL;
return bRetVal;
}
bool GetFileInfoString(const QString &fileName, const QString &name, QString &value)
{
TCHAR *ptszStr = NULL;
ptszStr = new TCHAR[1024];
LPCWSTR fileName_wstr = reinterpret_cast<LPCWSTR>(fileName.data());
LPCWSTR name_wstr = reinterpret_cast<LPCWSTR>(name.data());
BOOL bRet = GetFileInfoStringWinApi(fileName_wstr, name_wstr, ptszStr, 1024);
value = QString::fromWCharArray(ptszStr);
delete ptszStr;
ptszStr = NULL;
return bRet;
}
QString GetFileProductVersion(const QString &fileName)
{
QString version;
GetFileInfoString(fileName, "ProductVersion", version);
return version;
}
2.3 测试结果
int main(int argc, char *argv[])
{
QString fileName = "xxx//CZVisionCameraOperator.dll";
qDebug() << GetFileProductVersion(fileName);
return 0;
}
2.4 扩展
除版本信息,还可以获取文件说明、产品名称、版权、公司名称、原始文件名称等
FileDescription 文件说明
FileVersion 文件版本
ProductName 产品名称
ProductVersion 产品版本
LegalCopyright 版权
CompanyName 公司名称
OriginalFilename 原始文件名