Win32 获取EXE/DLL文件版本信息

CFileVersion.h

#pragma once#include <windows.h>
#include <string>
#include <tchar.h>#ifdef _UNICODE
using _tstring = std::wstring;
#else
using _tstring = std::string;
#endif// 版本号辅助类
class CVersionNumber
{
public:CVersionNumber() :m_nVer{ 0 } {};// 从版本字符串构造CVersionNumber(LPCTSTR lpStrVer) :m_nVer{ 0 }{_stscanf_s(lpStrVer, _T("%hd.%hd.%hd.%hd"), &m_nVer[0], &m_nVer[1], &m_nVer[2], &m_nVer[3]);}// 从指定版本号构造CVersionNumber(WORD v1, WORD v2, WORD v3, WORD v4) :m_nVer{ v1, v2, v3, v4 }{}// 从版本字符串构造CVersionNumber& operator = (LPCTSTR lpStrVer){_stscanf_s(lpStrVer, _T("%hd.%hd.%hd.%hd"), &m_nVer[0], &m_nVer[1], &m_nVer[2], &m_nVer[3]);return *this;}int CompareVersion(const CVersionNumber& ref){for (int i = 0; i < _countof(m_nVer); i++){if (m_nVer[i] != ref.m_nVer[i]){return (m_nVer[i] > ref.m_nVer[i] ? 1 : -1);}}return 0;}bool operator < (const CVersionNumber& ref){return CompareVersion(ref) < 0;}bool operator == (const CVersionNumber& ref){return CompareVersion(ref) == 0;}bool operator > (const CVersionNumber& ref){return CompareVersion(ref) > 0;}private:WORD m_nVer[4];         //版本号
};typedef struct _FILE_VERSION_INFO
{_tstring strComments;                       //文件注释_tstring strInternalName;                   //内部名称_tstring strProductName;                    //产品名称_tstring strCompanyName;                    //公司名称_tstring strLegalCopyright;                 //法律版权_tstring strProductVersion;                 //产品版本_tstring strFileDescription;                //文件描述_tstring strLegalTrademarks;                //合法商标_tstring strPrivateBuild;                   //私有构建_tstring strFileVersion;                    //文件版本_tstring strOriginalFilename;               //原始文件名_tstring strSpecialBuild;                   //特殊构建_tstring strFileVersionEx;                  //文件版本(从 VS_FIXEDFILEINFO中 获取)_tstring strProductVersionEx;               //产品版本(从 VS_FIXEDFILEINFO中 获取)CVersionNumber FileVerNumber;               //文件版本号CVersionNumber ProductVerNumber;            //产品版本号
}FILE_VERSION_INFO;class CFileVersion
{struct LANGANDCODEPAGE {WORD wLanguage;WORD wCodePage;LANGANDCODEPAGE():wLanguage(0),wCodePage(0){}};public:CFileVersion();~CFileVersion();CFileVersion operator = (const CFileVersion& r) = delete;static FILE_VERSION_INFO GetVersionInfo(const _tstring& strFile);static FILE_VERSION_INFO GetCurrentModuleVersionInfo();public:bool LoadFile(const _tstring& strFile);             //加载文件信息void Close();FILE_VERSION_INFO GetVersionInfo() const;           //整个版本信息_tstring GetComments() const;                       //文件注释_tstring GetInternalName() const;                   //内部名称_tstring GetProductName() const;                    //产品名称_tstring GetCompanyName() const;                    //公司名称_tstring GetLegalCopyright() const;                 //法律版权_tstring GetProductVersion() const;                 //产品版本_tstring GetFileDescription() const;                //文件描述_tstring GetLegalTrademarks() const;                //合法商标_tstring GetPrivateBuild() const;                   //私有版本_tstring GetFileVersion() const;                    //文件版本_tstring GetOriginalFilename() const;               //原始文件名_tstring GetSpecialBuild() const;                   //特别版本_tstring GetFileVersionEx() const;                  //文件版本(从 VS_FIXEDFILEINFO中 获取)_tstring GetProductVersionEx() const;               //产品版本(从 VS_FIXEDFILEINFO中 获取)VS_FIXEDFILEINFO GetFixedFileInfo() const;          //文件的版本信息private:_tstring _QueryInfo(const _tstring& strName) const;void _LoadAllInfo();LPVOID m_lpVerData;                                 //文件信息数据指针LANGANDCODEPAGE m_Translate;                        //语言代码页VS_FIXEDFILEINFO m_VsFixedFileInfo;                 //文件的版本信息FILE_VERSION_INFO m_VersionInfo;                    //版本信息
};

CFileVersion.cpp

#include "CFileVersion.h"
#include <tchar.h>
#include <strsafe.h>#pragma comment(lib, "Version.lib")typedef struct _FILE_VERSION_NUMBER
{WORD m_nVer[4];_FILE_VERSION_NUMBER() :m_nVer{0} {};_FILE_VERSION_NUMBER(LPCTSTR lpStrVer) :m_nVer{0}{_stscanf_s(lpStrVer, _T("%hd.%hd.%hd.%hd"),&m_nVer[0],&m_nVer[1],&m_nVer[2],&m_nVer[3]);}_FILE_VERSION_NUMBER& operator = (LPCTSTR lpStrVer){_stscanf_s(lpStrVer, _T("%hd.%hd.%hd.%hd"),&m_nVer[0],&m_nVer[1],&m_nVer[2],&m_nVer[3]);return *this;}int CompareVersion(const _FILE_VERSION_NUMBER& ref){for (int i = 0; i < _countof(m_nVer); i++){if (m_nVer[i] != ref.m_nVer[i]){return (m_nVer[i] > ref.m_nVer[i] ? 1 : -1);}}return 0;}bool operator < (const _FILE_VERSION_NUMBER& ref){return CompareVersion(ref) < 0;}bool operator == (const _FILE_VERSION_NUMBER& ref){return CompareVersion(ref) == 0;}bool operator > (const _FILE_VERSION_NUMBER& ref){return CompareVersion(ref) > 0;}}FILE_VERSION_NUMBER;#pragma pack(push)
#pragma pack(1)
// 包含文件的版本信息。 此信息与语言和代码页无关
// https://learn.microsoft.com/zh-cn/windows/win32/menurc/vs-versioninfo
typedef struct {WORD             wLength;       // VS_VERSIONINFO 结构的长度(以字节为单位),此长度不包括在 32 位边界上对齐任何后续版本资源数据的填充WORD             wValueLength;  // Value 成员的长度(以字节为单位)WORD             wType;         // 版本资源中的数据类型, 1: 资源包含文本数据 0: 版本资源包含二进制数据WCHAR            szKey[15];     // Unicode 字符串 L“VS_VERSION_INFO”WORD             Padding1;      // 在 32 位边界上对齐 Children 成员所需的任意或零个 WORD//VS_FIXEDFILEINFO Value//WORD             Padding2//WORD             Children
} VS_VERSIONINFO, * PVS_VERSIONINFO;#pragma pack(pop)CFileVersion::CFileVersion():m_lpVerData(NULL)
{memset(&m_VsFixedFileInfo, 0, sizeof(m_VsFixedFileInfo));
}CFileVersion::~CFileVersion()
{this->Close();
}FILE_VERSION_INFO CFileVersion::GetVersionInfo(const _tstring& strFile)
{CFileVersion verInfo;verInfo.LoadFile(strFile);return verInfo.GetVersionInfo();
}FILE_VERSION_INFO CFileVersion::GetCurrentModuleVersionInfo()
{TCHAR szBuf[MAX_PATH] = { 0 };::GetModuleFileName(NULL, szBuf, _countof(szBuf));return GetVersionInfo(szBuf);
}bool CFileVersion::LoadFile(const _tstring& strFile)
{PVOID pFsRedirectionOldValue = NULL;bool isDisableWow64Fs = false;bool isSuccess = false;UINT cbTranslate = 0;DWORD dwVerSize;if (strFile.empty()){return false;}this->Close();m_VersionInfo = FILE_VERSION_INFO();// 禁用文件重定向isDisableWow64Fs = ::Wow64DisableWow64FsRedirection(&pFsRedirectionOldValue);do{// 获取版本信息数据大小dwVerSize = ::GetFileVersionInfoSize(strFile.c_str(), 0);if (0 == dwVerSize){break;}// 分配版本信息缓冲m_lpVerData = ::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY, dwVerSize);if (!m_lpVerData){break;}// 获取版本信息if (!::GetFileVersionInfo(strFile.c_str(), 0, dwVerSize, m_lpVerData)){break;}// 获取语言代码LANGANDCODEPAGE* lpTranslate = NULL;if (!::VerQueryValue(m_lpVerData, _T("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate)){break;}m_Translate = *lpTranslate;// 获取 VS_FIXEDFILEINFO 信息PVS_VERSIONINFO lpVersion = (PVS_VERSIONINFO)m_lpVerData;if (0 != lpVersion->wValueLength){VS_FIXEDFILEINFO* pFixedFileInfo = (VS_FIXEDFILEINFO*)((LPBYTE)lpVersion + sizeof(VS_VERSIONINFO));DWORD dwAlign = 4;DWORD_PTR dwPadding = ((DWORD_PTR)pFixedFileInfo % dwAlign);if (0 != dwPadding){pFixedFileInfo = (VS_FIXEDFILEINFO*)((LPBYTE)pFixedFileInfo + (dwAlign - dwPadding));}m_VsFixedFileInfo = *pFixedFileInfo;}// 加载所有信息_LoadAllInfo();isSuccess = true;} while (false);// 不成功则关闭if (!isSuccess){this->Close();}// 恢复文件重定向if (isDisableWow64Fs){::Wow64RevertWow64FsRedirection(pFsRedirectionOldValue);}return isSuccess;
}void CFileVersion::Close()
{if (m_lpVerData){HeapFree(::GetProcessHeap(), 0, m_lpVerData);m_lpVerData = NULL;}
}void CFileVersion::_LoadAllInfo()
{m_VersionInfo.strComments = _QueryInfo(_T("Comments"));m_VersionInfo.strInternalName = _QueryInfo(_T("InternalName"));m_VersionInfo.strProductName = _QueryInfo(_T("ProductName"));m_VersionInfo.strCompanyName = _QueryInfo(_T("CompanyName"));m_VersionInfo.strLegalCopyright = _QueryInfo(_T("LegalCopyright"));m_VersionInfo.strProductVersion = _QueryInfo(_T("ProductVersion"));m_VersionInfo.strFileDescription = _QueryInfo(_T("FileDescription"));m_VersionInfo.strLegalTrademarks = _QueryInfo(_T("LegalTrademarks"));m_VersionInfo.strPrivateBuild = _QueryInfo(_T("PrivateBuild"));m_VersionInfo.strFileVersion = _QueryInfo(_T("FileVersion"));m_VersionInfo.strOriginalFilename = _QueryInfo(_T("OriginalFilename"));m_VersionInfo.strSpecialBuild = _QueryInfo(_T("SpecialBuild"));m_VersionInfo.strFileVersionEx = GetFileVersionEx();m_VersionInfo.strProductVersionEx = GetProductVersionEx();m_VersionInfo.FileVerNumber = m_VersionInfo.strFileVersionEx.c_str();m_VersionInfo.ProductVerNumber = m_VersionInfo.strProductVersionEx.c_str();}_tstring CFileVersion::_QueryInfo(const _tstring& strName) const
{_tstring strRes;TCHAR strQuery[MAX_PATH] = { 0 };LPCTSTR lpQueryRes = NULL;UINT uQueryCchSize;do{if (!m_lpVerData){break;}(void)::StringCchPrintf(strQuery, _countof(strQuery),_T("\\StringFileInfo\\%04x%04x\\%s"),m_Translate.wLanguage,m_Translate.wCodePage,strName.c_str());if (!::VerQueryValue(m_lpVerData, strQuery, (LPVOID*)&lpQueryRes, &uQueryCchSize)){break;}strRes = lpQueryRes;} while (false);return strRes;
}_tstring CFileVersion::GetComments() const
{return m_VersionInfo.strComments;
}_tstring CFileVersion::GetInternalName() const
{return m_VersionInfo.strInternalName;
}_tstring CFileVersion::GetProductName() const
{return m_VersionInfo.strProductName;
}_tstring CFileVersion::GetCompanyName() const
{return m_VersionInfo.strCompanyName;
}_tstring CFileVersion::GetLegalCopyright() const
{return m_VersionInfo.strLegalCopyright;
}_tstring CFileVersion::GetProductVersion() const
{return m_VersionInfo.strProductVersion;
}_tstring CFileVersion::GetFileDescription() const
{return m_VersionInfo.strFileDescription;
}_tstring CFileVersion::GetLegalTrademarks() const
{return m_VersionInfo.strLegalTrademarks;
}_tstring CFileVersion::GetPrivateBuild() const
{return m_VersionInfo.strPrivateBuild;
}_tstring CFileVersion::GetFileVersion() const
{return m_VersionInfo.strFileVersion;
}_tstring CFileVersion::GetOriginalFilename() const
{return m_VersionInfo.strOriginalFilename;
}_tstring CFileVersion::GetSpecialBuild() const
{return m_VersionInfo.strSpecialBuild;
}_tstring CFileVersion::GetFileVersionEx() const
{TCHAR szBuf[MAX_PATH] = { 0 };(void)::StringCchPrintf(szBuf, _countof(szBuf), _T("%hd.%hd.%hd.%hd"),HIWORD(m_VsFixedFileInfo.dwFileVersionMS),LOWORD(m_VsFixedFileInfo.dwFileVersionMS),HIWORD(m_VsFixedFileInfo.dwFileVersionLS),LOWORD(m_VsFixedFileInfo.dwFileVersionLS));return szBuf;
}_tstring CFileVersion::GetProductVersionEx() const
{TCHAR szBuf[MAX_PATH] = { 0 };(void)::StringCchPrintf(szBuf, _countof(szBuf), _T("%hd.%hd.%hd.%hd"),HIWORD(m_VsFixedFileInfo.dwProductVersionMS),LOWORD(m_VsFixedFileInfo.dwProductVersionMS),HIWORD(m_VsFixedFileInfo.dwProductVersionLS),LOWORD(m_VsFixedFileInfo.dwProductVersionLS));return szBuf;
}VS_FIXEDFILEINFO CFileVersion::GetFixedFileInfo() const
{return m_VsFixedFileInfo;
}FILE_VERSION_INFO CFileVersion::GetVersionInfo() const
{return m_VersionInfo;
}

main.cpp

#include <locale.h>
#include "Win32Utils/CFileVersion.h"int _tmain(int argc, LPCTSTR argv[])
{setlocale(LC_ALL, "");FILE_VERSION_INFO info = CFileVersion::GetCurrentModuleVersionInfo();return 0;
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/689377.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

Qt程序设计-无边框可移动可拖拽调整大小窗体

本文讲解Qt-无边框可移动可拖拽调整大小窗体。 通过鼠标的按下移动进行窗体的移动,拖拽调整窗体大小。 实现过程如下: 创建QWidget窗体,添加一个按钮控制窗体的关闭。 #ifndef MYWIDGET_H #define MYWIDGET_H#include <QWidget>#include <QMouseEvent> //定…

【天衍系列 05】Flink集成KafkaSink组件:实现流式数据的可靠传输 高效协同

文章目录 01 KafkaSink 版本&导言02 KafkaSink 基本概念03 KafkaSink 工作原理1.初始化连接2.定义序列化模式3.创建KafkaSink算子4.创建数据源5.将数据流添加到KafkaSink6.内部工作机制 04 KafkaSink参数配置05 KafkaSink 应用依赖06 KafkaSink 快速入门6.1 包结构6.2 项目…

【深度学习:数据注释工具】构建与购买:从业者的经验教训

【深度学习&#xff1a;数据注释工具】构建与购买&#xff1a;从业者的经验教训 为什么数据注释团队需要标记工具&#xff1f;您的软件工程团队是否有时间/资源来构建数据注释解决方案&#xff1f;为您的项目构建数据注释工具需要多长时间&#xff1f;将开发外包给第三方会更有…

异地组网延迟怎么解决问题?

异地组网中的延迟问题可以通过SD-WAN&#xff08;Software-Defined Wide Area Network&#xff09;技术进行解决。SD-WAN可以通过优化网络流量和智能路由选择来降低延迟&#xff0c;提高应用程序的性能和用户体验。接下来将介绍使用SD-WAN解决异地组网延迟问题的常用方法。 1.…

SSH密钥认证登陆流程(Vscode连接到远程)

目录 前言连接远程步骤1. 下载工具包wsCli到本地机器2. 本地机器上生成ssh密钥3. 在服务器上安装公钥4. vscode连接到远程 参考资料 前言 SSH&#xff08;Secure Shell&#xff09;是一种用于远程登录和安全传输数据的网络协议。它提供了两种主要的远程连接方式&#xff1a; 密…

学习总结18

# 营救 ## 题目背景 “咚咚咚……”“查水表&#xff01;”原来是查水表来了&#xff0c;现在哪里找这么热心上门的查表员啊&#xff01;小明感动得热泪盈眶&#xff0c;开起了门…… ## 题目描述 妈妈下班回家&#xff0c;街坊邻居说小明被一群陌生人强行押上了警车&#…

有趣的CSS - 新拟态输入框

我是 Just&#xff0c;这里是「设计师工作日常」&#xff0c;《有趣的css》系列已更新 11 篇了&#xff0c;今天这篇是关于新拟态风格的一个输入框效果&#xff0c;希望你们喜欢。 目录 页面效果核心代码html代码css代码 完整代码html页面css样式 页面效果 此效果使用 css 中 b…

C/C++输出输出相关问题

C/C输出输出相关问题 scanf(“%d”),如果缓存区的开始是数字&#xff0c;scanf会读入&#xff0c;直到遇见非数字字符&#xff0c;否则远不会读入 #include<iostream> using namespace std; int main() {int a[100];char c[100];// scanf的返回值为“所输入的数据与格式字…

html5播放 m3u8

注意&#xff1a;m3u8地址要为网络地址&#xff0c;直接把代码复制为html直接在本地打开&#xff0c;可能不行&#xff0c;需要放在nginx或者apache或者其他的web服务器上运行。 <!DOCTYPE html> <html> <head><meta charsetutf-8 /><title>测试…

通过kafka学习数据一致性

kafka哪些环节存在数据不一致 数据复制 数据从主节点&#xff08;leader&#xff09;复制到从节点&#xff08;follower&#xff09;的过程中&#xff0c;由于网络延迟、节点故障或其他原因 可能导致从节点未能及时获取或处理主节点的数据变更&#xff0c;从而产生数据不一致…

PDF控件Spire.PDF for .NET【安全】演示:如何在 PDF 中添加签名字段

Spire.PDF for .NET 是一款独立 PDF 控件&#xff0c;用于 .NET 程序中创建、编辑和操作 PDF 文档。使用 Spire.PDF 类库&#xff0c;开发人员可以新建一个 PDF 文档或者对现有的 PDF 文档进行处理&#xff0c;且无需安装 Adobe Acrobat。 E-iceblue 功能类库Spire 系列文档处…

js之es新特性

ES6 (ECMAScript 2015) 1. let 和 const let 允许声明一个块作用域的变量。const 允许声明一个块作用域的常量。 let x 10; if (x 10) {let x 20; // 这里的 x 和外面的 x 不是同一个变量console.log(x); // 20 } console.log(x); // 10const y 5; // y 10; // 会抛出错…

PyCharm 新建目录 (directory or folder)

PyCharm 新建目录 [directory or folder] 1. 新建目录2. Enter new directory name -> OKReferences 1. 新建目录 right mouse click on the project -> New -> Directory 2. Enter new directory name -> OK ​​​ References [1] Yongqiang Cheng, https:/…

go redis

go redis 快速入门 安装&#xff1a; go get github.com/redis/go-redis/v9然后创建客户端&#xff1a; package mainimport "github.com/redis/go-redis/v9"func main() {rdb : redis.NewClient(&redis.Options{Addr: "47.109.87.142:6379",Pa…

C++_design_model_observer

/* 观察者模式是一种常用的设计模式&#xff0c;用于在对象之间建立一种一对多的依赖关系&#xff0c;当被观察的对象发生变化时&#xff0c; 所有依赖于它的对象都能够得到通知并自动更新。下面是一个使用C实现观察者模式的例子&#xff1a; */#include <iostream> #inc…

Redis篇----第六篇

系列文章目录 文章目录 系列文章目录前言一、Redis 的持久化机制是什么?各自的优缺点?二、Redis 常见性能问题和解决方案:三、redis 过期键的删除策略?前言 前些天发现了一个巨牛的人工智能学习网站,通俗易懂,风趣幽默,忍不住分享一下给大家。点击跳转到网站,这篇文章…

已经打包好了的vue dist文件夹,如何用electron打包成exe桌面应用

先在项目根目录下&#xff08;非dist根目录&#xff09;安装electron electron-packager npm install electron再在项目根目录下&#xff08;非dist根目录&#xff09;安装electron-packager npm install electron-packager 然后在dist文件夹下创建main.js文件,内容为 cons…

如何查看springboot依赖的JDK版本

通过maven构建Java项目或者使用源代码进行Java编译时&#xff0c;常常遇到JDK版本和Springboot版本不匹配的问题&#xff0c;导致编译失败&#xff0c;比如出现如下错误&#xff1a; org/springframework/beans/factory/InitializingBean.class [ERROR] 类文件具有错误的…

Unix I/O 模型及Java I/O 模型详解

在Unix Socket的输入操作中&#xff0c;可以将其分为以下几个阶段&#xff1a; 等待数据就绪(内核空间)&#xff1a; 在这个阶段&#xff0c;应用程序通过调用阻塞式的读取函数&#xff08;如recv&#xff09;或非阻塞式的读取函数&#xff08;如recv、recvfrom&#xff09;等待…

可扩展性和性能:数字化成功的支柱

在动态的数字技术世界中,用户的期望和对数字系统的需求不断增加,可扩展性和性能已成为孪生要素。在本文中,我们将全面探讨软件和系统设计的两个基本方面:水平扩展、垂直扩展和性能优化。 简介:关键当务之急 考虑一个场景:您正在管理一个电子商务平台,限时抢购导致网站…