QT获取dll库文件详细信息
一、需求背景
获取软件下依赖的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 zeroDWORD dwLen = 0;BYTE *pVersionInfo = NULL;BOOL bRetVal;VS_FIXEDFILEINFO FileVersion;HMODULE hVerDll;hVerDll = LoadLibrary(_T("VERSION.dll"));if (hVerDll == NULL){return FALSE;}#ifdef _UNICODEtypedef DWORD(WINAPI * Fun_GetFileVersionInfoSize)(LPCTSTR, DWORD *);typedef BOOL(WINAPI * Fun_GetFileVersionInfo)(LPCTSTR, DWORD, DWORD, LPVOID);typedef BOOL(WINAPI * Fun_VerQueryValue)(LPCVOID, LPCTSTR, LPVOID, PUINT);
#elsetypedef DWORD(WINAPI * Fun_GetFileVersionInfoSize)(LPCSTR, DWORD *);typedef BOOL(WINAPI * Fun_GetFileVersionInfo)(LPCSTR, DWORD, DWORD, LPVOID);typedef BOOL(WINAPI * Fun_VerQueryValue)(LPCVOID, LPCSTR, LPVOID, PUINT);
#endifFun_GetFileVersionInfoSize pGetFileVersionInfoSize;Fun_GetFileVersionInfo pGetFileVersionInfo;Fun_VerQueryValue pVerQueryValue;#ifdef _UNICODEpGetFileVersionInfoSize = (Fun_GetFileVersionInfoSize)::GetProcAddress(hVerDll, "GetFileVersionInfoSizeW");pGetFileVersionInfo = (Fun_GetFileVersionInfo)::GetProcAddress(hVerDll, "GetFileVersionInfoW");pVerQueryValue = (Fun_VerQueryValue)::GetProcAddress(hVerDll, "VerQueryValueW");
#elsepGetFileVersionInfoSize = (Fun_GetFileVersionInfoSize)::GetProcAddress(hVerDll, "GetFileVersionInfoSizeA");pGetFileVersionInfo = (Fun_GetFileVersionInfo)::GetProcAddress(hVerDll, "GetFileVersionInfoA");pVerQueryValue = (Fun_VerQueryValue)::GetProcAddress(hVerDll, "VerQueryValueA");
#endifstruct TRANSLATION{WORD langID; // language IDWORD charset; // character set (code page)} Translation;Translation.langID = 0x0409; //Translation.charset = 1252; // default = ANSI code pagedwLen = pGetFileVersionInfoSize(pFileName, &dwDummyHandle);if (dwLen == 0){bRetVal = FALSE;goto End;}pVersionInfo = new BYTE[dwLen]; // allocate version infobRetVal = 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 原始文件名
相关文章:
QT获取dll库文件详细信息
一、需求背景获取软件下依赖的dll库的版本信息,如下图所示版本为1.0.7.1018二、实现方法2.1步骤windows下实现,基于version.lib(version.dll)提供的函数获取这些信息首先使用GetFileVersionInfoSizeA(W)获取VersionInfo的大小,申请缓冲区&…...
常见的电脑运行卡顿原因及解决方法
大家在日常使用电脑过程中,会发现多开几个文件就卡顿,其实很多时候都跟C盘长期不清理有关,C盘的内存被下载的软件安装包、页面文件、休眠文件、更新文件等一系列的文件占据。大的文件甚至能占到20-30G,驱动人生就为大家带来几种解…...
案例08-让软件的使用者成为软件的设计者
一:背景介绍 对于需求的开发每天可能都会有上线的情况,为了防止每次上线拉取代码或者修改配置而引发的冲突以及发生了冲突应该找谁一起确定一下代码留下那一部分的情况。所以在开发的群中会有一个表格来记录每个需求上线修改的环境、是否修改数据库、是否…...
QinQ与Vlan Mapping讲解
目录 QinQ Vlan扩展 QinQ实现方式 QinQ实验配置 Vlan Mapping Vlan映射 映射方式 配置命令 QinQ Vlan扩展 QinQ全称为802.1Q-in-802.1Q,为Vlan扩展技术,在802.1Q标签报文的基础上再增加一层802.1Q标签,实现扩展Vlan空间;可…...
golang 获取token方法
package main import ( "fmt" "time" "github.com/dgrijalva/jwt-go" ) const ( SECRETKEY "202203021124355xxx" //私钥 ) // 自定义 Claims type CustomClaims struct { UserId int64 jwt.StandardClaims } func main() { //生…...
【数据库专题】数据库Mongodb之深入认知云计算三种服务方式、mongodb特点、mongodb重要进程 mongod、mongo、其他进程区别
文章目录一、什么是云计算1. IaaS:基础设施即服务2. SaaS:软件即服务3. PaaS:平台即服务二、大数据与云计算关系三、什么是MongoDB四、大数据与MongoDB五、MongoDB特点六、安装MongoDB七、重要进程介绍7.1 mongod进程7.2 mongo进程7.3 其他进程7.3.1 mongodump重建数据库7.3.2 …...
ccc-pytorch-小实验合集(4)
文章目录一、 Himmelblau 优化二、多分类实战-Mnist三、Sequential与CPU加速-Mnist四、visidom可视化一、 Himmelblau 优化 Himmelblau 是一个具有4个最优值的2维目标函数。其函数和最优值点如下: 图象绘制: import numpy as np from matplotlib impo…...
webrtc音频系列——4、RTP与RTCP协议
如果让你从0开发一套实时互动直播系统,你首先要选择网络传输协议。UDP 还是 TCP?答案是:UDP。为什么实时传输不能用 TCP ?TCP 的目的就是实现数据的可靠传输,因此他有一套 握手,发送 -> 确认,…...
C++枚举解读(enum)
提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录前言一、枚举是什么?二、使用步骤1.作用域2.隐式类型转换3.显式指定枚举值类型4.指定枚举值的值4.整形显式转换成枚举总结前言 对于开发C来说࿰…...
OSCP-课外5(Web图片泄露服务信息、日志中毒)
目录 一、主机发现与端口扫描 二、Web信息收集 三、系统信息收集与提权 一、主机发现与端口扫描...
汇编指令学习(ADD,SUB,MUL,DIV,XADD,INC,DEC,NEG)
一、ADD加法操作指令将eax置1,ebx置2,运行下面命令,将结果保存到eaxadd eax,ebx扩展:adc需要再加上CF标志位的值adc eax,ebx二、SUB减法操作指令将eax置3,ebx置2,运行下面命令,将结果…...
【电源专题】案例:充电芯片损坏为什么判断是从NTC进入的EOS
最近有发现一个异常就是测试部测试测试然后充电芯片就无法使用了。通过二极管特性分析(参考文章:电源专题】案例:电源芯片厂家怎么判断电源芯片端口是否损坏)是NTC管脚已经损坏对地短路了。但是以前没有发现这个问题,最近更换了芯片后就发现的特别明显。 首先分析一下现在…...
C语言中的数据储存规则
写在开头 关于复习的相关内容其实从一开始就列出了大纲,但是迟迟没有开始复习,一方面是因为学校学业却是繁忙,另一方面还是内心对旧知识掌握不熟练需要再学一遍的畏惧和懒惰,但如今,复习必须开始了。今天我从C语言的最…...
Android kotlin实战之协程suspend详解与使用
前言 Kotlin 是一门仅在标准库中提供最基本底层 API 以便各种其他库能够利用协程的语言。与许多其他具有类似功能的语言不同,async 与 await 在 Kotlin 中并不是关键字,甚至都不是标准库的一部分。此外,Kotlin 的 挂起函数 概念为异步操作提供…...
Pycharm中的Virtualenv Environment、Conda Environment
版本一 Conda Environment该不该选? 先说结论,该选,而且还是正解。前提是你打算"用Anaconda来管理各种Python环境,同时管理Python下面的各种包"。 选了Conda Environment意味着什么? 意味着你以后如果要装新的包的话…...
C++容器介绍:vector
目录vector简介使用方法1.头文件2.vector声明及初始化3.vector基本操作(1). 容量(2). 修改(3)迭代器(4)元素的访问(5)算法vector 简介 vector是表示可变大小数组的序列容器。就像数组一样,vector也采用的连续存储空间来存储元素。也就是意味着可以采用下标对vecto…...
抗锯齿和走样(笔记)
Artifacts(瑕疵): 比如人眼采样频率跟不上陀螺的旋转速度,这时就有可能看到陀螺在反方向旋转怎么做抗锯齿(滤波): 在采样之前先进行一个模糊操作,可以降低锯齿的明显程度 通过傅里叶…...
线程池的使用——线程池的创建方式
线程池的使用——创建线程线程池的创建线程池的创建方式Executors.newFixedThreadPool:Executors.newCachedThreadPool:Executors.newSingleThreadExecutor:Executors.newScheduledThreadPool:Executors.newSingleThreadScheduled…...
代码随想录算法训练营day47 |动态规划 198打家劫舍 213打家劫舍II 337打家劫舍III
day47198.打家劫舍1.确定dp数组(dp table)以及下标的含义2.确定递推公式3.dp数组如何初始化4.确定遍历顺序5.举例推导dp数组213.打家劫舍II情况一:考虑不包含首尾元素情况二:考虑包含首元素,不包含尾元素情况三&#x…...
项目设计模式和规范
1、责任链模式 自己的理解:避免发生方与接收方解耦 优点:①降低发送方与接收方的耦合 ②简化他们对象 ③方便扩展新增 处理者 缺点:①不方便排错 ②性能问题,且使用不当容易搞出死循环 应用场景:拦截器 Interceptor和过滤器 filter:符合模式的进行拦截或者过滤到,然…...
无线WiFi安全渗透与攻防(一)之无线安全环境搭建
无线安全环境搭建 1.802.11标准 (1).概念 802.11标准是1997年IEEE最初制定的一个WLAN标准,工作在2.4GHz开放频段,支持1Mbit/s和2Mbit/s的数据传输速率,定义了物理层和MAC层规范,允许无线局域网及无线设备…...
【matplotlib】可视化解决方案——如何解决matplotlib中文乱码问题
问题概述 Matplotlib 默认不支持中文字体,这是因为 matplotlib 只支持 ASCII 字符,但是国人使用 matplotlib 肯定需要中文标注。如下图所示,当不对 Matplotlib 进行设置,而直接使用中文时,绘制的图像会出现中文乱码。…...
JAVA开发中GC日志打印简单通用的配置详解
如何配置一个完美的JVM日志打印信息 打印内容 打印基本的GC信息 打印对象分布情况 GC后打印堆数据 打印STW时间 打印safepoint信息 打印Reference处理信息 综上所述,最终的参数如下: 还有哪些问题呢?是不是有文件输出更好? 打印日…...
十进制的小数如何转二进制?二进制表示的小数如何转十进制?
😄 基础不牢,地动山摇~ 补补基础~ 文章目录 1、十进制的小数转二进制?2、二进制表示的小数转十进制?3、做道coding题巩固下:1、十进制的小数转二进制? 整数部分: 用普通的二进制表示即可。小数部分: 首先,将小数部分乘以2,取出整数部分作为二进制表示的第1位;然后…...
klipper使用webcam设置多个摄像头方式
一、前言 使用klipper设置多个摄像头,折腾了好些天,网上资料很少,这里写一个帖子记录一下 二、环境 参考链接:https://www.cnblogs.com/sjqlwy/p/klipper_webcam.html 我的klipper安装在香橙派上面,系统是debian&a…...
风力发电机组浪涌保护器安全防护方案
风机的庞大与危险高空作业注定了其在基建和维护中不易操作,风机设备的主电源、过程控制、网络与通讯、现场设备需要高等级的防雷浪涌保护器冲击保护,提高系统及设备的可靠性和可用性。风电场的主要发电设备风力发电机组“大风车”是风电场的主要发电设备…...
【剑指offer】JZ7 重建二叉树、JZ9 用两个栈实现队列
\描述: 给定节点数为 n 的二叉树的前序遍历和中序遍历结果,请重建出该二叉树并返回它的头结点。 例如输入前序遍历序列{1,2,4,7,3,5,6,8}和中序遍历序列{4,7,2,1,5,3,8,6},则重建出如下图所示。 思路: 题上给了我们前序遍历(根 …...
ElasticSearch - SpringBoot整合ES之查询所有 match_all
文章目录1. 数据准备2. 全量查询 match_all3. 使用 boost 参数更改 _score官方文档地址:https://www.elastic.co/guide/en/elasticsearch/reference/index.html权威指南:https://www.elastic.co/guide/cn/elasticsearch/guide/current/structured-search…...
详谈IIC
前言 在嵌入式底层系统中,常见的通讯方式,串口,IIC,SPI,IIS等,一般IIC,SPI,IIS更多的采取IO模拟,其余CAN,UART均是硬件设计直接支持,而IIC主要用于多数传感器数据的读写,…...
【Autoware】采集实验数据bag包并仿真运行
文章目录1. 官方demo包2. 控制底层地图采集3. 感知定位4. 规划控制5. 仿真或实车运行1. 官方demo包 wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_data.tar.gz wget http://db3.ertl.jp/autoware/sample_data/sample_moriyama_150324.tar.gz官方示例包的网上…...
湖南英文网站建设/seo推广排名重要吗
undefined:声明了变量,但是没有赋值undeclared:没有声明变量就直接使用 如上图,num 就是undefined,arr 则是 undeclared。...
在网上怎么做网站/外贸网站推广方法之一
题目链接 题目大意 给你一个整数D,有一个无向图,图的节点为 D 的因子,若 x % y 0 && x / y 是一个质数,则节点 x 和 y 有一条无向边,边权为 是 x 的因子但不是 y 的因子的数的个数。有 q 次询问,…...
门户网站建设好处/网络营销模式包括哪些
上一次我们一起重温了JS中数组相关的内容,这一次我们要来学习ES6新引入的两个数据结构:map和set。map和对象比较像,可以用键来获取值,set则和数组比较像,但是不允许出现重复的值。下面我们就进入详细地学习吧ÿ…...
wordpress 模板教程/google推广专员招聘
EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器出现no compatible source was found for this media问题的解决参考文章: (1)EasyDSS高性能RTMP、HLS(m3u8)、HTTP-FLV、RTSP流媒体服务器出现no compatible source was found for…...
个人备案 做网站/网站优化和网站推广
“我们现在认为,激光雷达行业的竞争发展到了一个新的里程碑,实现量产交付是激光雷达赛道的新门槛。”12月16日,在图达通年度媒体沙龙上,其联合创始人兼CEO鲍君威认为。 高工智能汽车注意到,量产交付能力,对…...
正规做兼职的网站/免费的推文制作网站
数组的实例上都有一个叫做 forEach 的方法,这个方法定义在 Array.prototype 上,所以数组的所有实例都可以使用 forEach 这个方法。 forEach 方法的语法结构如下: 1 var ary [1, 2, 3, 4, 5, 5, 6, 8, 9]; 2 ary.forEach(function(index,…...