QT获取dll库文件详细信息

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6

一、需求背景

获取软件下依赖的dll库的版本信息如下图所示版本为1.0.7.1018

二、实现方法

2.1步骤

windows下实现基于version.lib(version.dll)提供的函数获取这些信息

  1. 首先使用GetFileVersionInfoSizeA(W)获取VersionInfo的大小申请缓冲区

  1. 接着使用GetFileVersionInfoA(W)获取VersionInfo数据到缓冲区

  1. 接着使用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 原始文件名

阿里云国内75折 回扣 微信号:monov8
阿里云国际,腾讯云国际,低至75折。AWS 93折 免费开户实名账号 代冲值 优惠多多 微信号:monov8 飞机:@monov6