当前位置: 首页 > news >正文

QT获取dll库文件详细信息

一、需求背景

获取软件下依赖的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 原始文件名

相关文章:

  • 常用Swagger注解汇总
  • 【Spring】掌握 Spring Validation 数据校验
  • 【Linux】项目自动化构建工具——make/Makefile
  • 部署OpenStack
  • 网络总结知识点(网络工程师必备)一
  • Java中常用的七种队列你了解多少?
  • 专治Java底子差,不要再认为泛型就是一对尖括号了
  • 《计算机系统基础》——数据的表示
  • 2023-3-2 刷题情况
  • 【数据结构】八大经典排序总结
  • 嵌入式学习笔记——基于Cortex-M的单片机介绍
  • 把数组里面数值排成最小的数
  • CEC2017:斑马优化算法(Zebra Optimization Algorithm,ZOA)求解cec2017(提供MATLAB代码)
  • Java并发简介(什么是并发)
  • 【uniapp】getOpenerEventChannel().once 接收参数无效的解决方案
  • 收藏网友的 源程序下载网
  • 「面试题」如何实现一个圣杯布局?
  • 【108天】Java——《Head First Java》笔记(第1-4章)
  • 11111111
  • android 一些 utils
  • canvas 五子棋游戏
  • ES6之路之模块详解
  • Fundebug计费标准解释:事件数是如何定义的?
  • js算法-归并排序(merge_sort)
  • Lsb图片隐写
  • Perseus-BERT——业内性能极致优化的BERT训练方案
  • Python十分钟制作属于你自己的个性logo
  • 不上全站https的网站你们就等着被恶心死吧
  • 多线程事务回滚
  • 软件开发学习的5大技巧,你知道吗?
  • 山寨一个 Promise
  • 通信类
  • 优化 Vue 项目编译文件大小
  • 曾刷新两项世界纪录,腾讯优图人脸检测算法 DSFD 正式开源 ...
  • #考研#计算机文化知识1(局域网及网络互联)
  • #控制台大学课堂点名问题_课堂随机点名
  • $(function(){})与(function($){....})(jQuery)的区别
  • (01)ORB-SLAM2源码无死角解析-(56) 闭环线程→计算Sim3:理论推导(1)求解s,t
  • (39)STM32——FLASH闪存
  • (delphi11最新学习资料) Object Pascal 学习笔记---第8章第5节(封闭类和Final方法)
  • (PyTorch)TCN和RNN/LSTM/GRU结合实现时间序列预测
  • (rabbitmq的高级特性)消息可靠性
  • (Redis使用系列) Springboot 实现Redis 同数据源动态切换db 八
  • (八)Docker网络跨主机通讯vxlan和vlan
  • (八)五种元启发算法(DBO、LO、SWO、COA、LSO、KOA、GRO)求解无人机路径规划MATLAB
  • (第一天)包装对象、作用域、创建对象
  • (附源码)apringboot计算机专业大学生就业指南 毕业设计061355
  • (附源码)springboot车辆管理系统 毕业设计 031034
  • (附源码)SSM环卫人员管理平台 计算机毕设36412
  • (附源码)ssm跨平台教学系统 毕业设计 280843
  • (免费领源码)Java#ssm#MySQL 创意商城03663-计算机毕业设计项目选题推荐
  • (五)Python 垃圾回收机制
  • (学习日记)2024.04.10:UCOSIII第三十八节:事件实验
  • (原創) 人會胖會瘦,都是自我要求的結果 (日記)
  • (转)Oracle 9i 数据库设计指引全集(1)