【Windows + Win32API + winver】版本号系列API解析
winver.h API解析
详见https://docs.microsoft.com/en-us/windows/win32/menurc/version-information
接口说明
GetFileVersionInfoSize(A/W)
获取一个二进制文件的版本号信息的大小, 必须先调用该函数确定了版本信息大小后分配足够内存,然后再调用GetFileVersionInfo获取具体的版本信息。
https://docs.microsoft.com/en-us/windows/win32/api/winver/nf-winver-getfileversioninfosizea
// param: lpdwHandle 在win32中已经废弃, 只需传入第一个参数,即文件名
// return: 返回该文件版本号信息的长度
DWORD GetFileVersionInfoSizeA(LPCSTR lptstrFilename, LPDWORD lpdwHandle);
GetFileVersionInfo(A/W)
获取一个二进制文件的版本号信息, 需要传入一个buf承载数据
// param: dwHandle 在win32中废弃。 传入文件名、buf长度、buf指针即可
BOOL GetFileVersionInfoW(
LPCWSTR lptstrFilename,
DWORD dwHandle,
DWORD dwLen,
LPVOID lpData
);
VerQueryValue
从GetFileVersionInfo
中获取到的版本号信息是字节流,无法解析,需要通过该接口进行解析
// param: 传入 版本号数据、想获取的数据内容, 然后传入一个指针和len作为出参,承载数据内容的指针以及长度
BOOL VerQueryValueA(
LPCVOID pBlock,
LPCSTR lpSubBlock,
LPVOID *lplpBuffer,
PUINT puLen
);
示例代码
#include <iostream>
#include <string>
#include <windows.h>
#include <tchar.h>
using namespace std;
int main()
{
wstring file = _T("C:\\Program Files\\Notepad++\\notepad++.exe");
do {
DWORD tmp = 0;
DWORD size = GetFileVersionInfoSize(file.c_str(), &tmp);
if (size == 0) {
cout << "Get size failed, err:"<<GetLastError()<< endl;
break;
}
VS_FIXEDFILEINFO* datas = (VS_FIXEDFILEINFO*)(new BYTE[size + 1]);
if (!GetFileVersionInfo(file.c_str(), 0, size, datas)) {
cout << "Get file version failed." << endl;
break;
}
UINT len;
VS_FIXEDFILEINFO* verInfo = nullptr;
if (VerQueryValue(datas, TEXT("\\"), reinterpret_cast<void**>(&verInfo), &len) == FALSE) {
break;
}
DWORD major = HIWORD(verInfo->dwFileVersionMS);
DWORD minor= LOWORD(verInfo->dwFileVersionMS);
DWORD build= HIWORD(verInfo->dwFileVersionLS);
DWORD revision= LOWORD(verInfo->dwFileVersionLS);
printf("get cmd.exe version : (%u.%u.%u.%u)\n", major, minor, build, revision);
if (datas != nullptr) {
delete[] datas;
}
} while (0);
return 0;
}
输出
get notepad++.exe version : (7.8.8.0)