c++ 以编程方式从Windows资源文件中提取版本信息[重复]

mxg2im7a  于 12个月前  发布在  Windows
关注(0)|答案(1)|浏览(167)

此问题在此处已有答案

how to use the GetFileVersionInfo function?(1个答案)
9天前关闭
Win10,C++20,MSVS Community 17.8.3
我正试图从MSVS的资源编辑器(解决方案资源管理器>资源文件>添加>资源>版本)中创建的已编译的.rc文件(.res)中检索文件版本信息。
版本资源.rc包含值为1, 0, 0, 1的FILEVERSION键和值为1, 0, 0, 1的PRODUCTVERSION键,并编译为.res文件。
我使用下面的代码来加载资源并提取文件版本信息。该项目编译和链接w/o错误或警告。我希望输出反映资源文件的内容。

#include <iostream>
#include <format>
#include "resource.h"

using std::cout;
using std::cerr;
using std::endl;
using std::format;

int main() {
    struct VersionInfo {
        DWORD dwFileVersionMS;
        DWORD dwFileVersionLS;
        DWORD dwProductVersionMS;
        DWORD dwProductVersionLS;
    };

    // Update the resource identifier to reflect the file name and ID
    HRSRC hVersionResource = FindResource(NULL, MAKEINTRESOURCE(1), RT_VERSION);

    if (!hVersionResource) {
        cerr << "Error: Could not find version resource." << endl;
        return -1;
    }

    HGLOBAL hVersionData = LoadResource(NULL, hVersionResource);

    if (!hVersionData) {
        cerr << "Error: Could not load version resource." << endl;
        return -1;
    }

    LPVOID pVersionData = LockResource(hVersionData);

    if (!pVersionData) {
        cerr << "Error: Could not lock version resource." << endl;
        return -1;
    }

    VersionInfo* versionInfo = (VersionInfo*)pVersionData;

    // Access and format version information
    cout << format("File version: {}.{}.{}.{}\n",
        HIWORD(versionInfo->dwFileVersionMS),
        LOWORD(versionInfo->dwFileVersionMS),
        HIWORD(versionInfo->dwFileVersionLS),
        LOWORD(versionInfo->dwFileVersionLS));

    cout << format("Product version: {}.{}.{}.{}\n",
        HIWORD(versionInfo->dwProductVersionMS),
        LOWORD(versionInfo->dwProductVersionMS),
        HIWORD(versionInfo->dwProductVersionLS),
        LOWORD(versionInfo->dwProductVersionLS));

    // Use other version information fields and format with format as needed

    FreeResource(hVersionData);
    return 0;
}

字符串
然而,每次我运行代码时,输出都是:

File version: 52.792.86.0
Product version: 95.83.69.86


我已经在how to use the GetFileVersionInfo function?上查看了答案,但觉得可能有一种更新的、更干净的方法,可以避免原始的new[]/delete[]调用。
我错过了什么?

oknwwptz

oknwwptz1#

花了一点时间,但我制作了来自@273K建议的成功代码,并从MS文档页面,Codeium和Bing Chat获得了一些帮助。

DWORD infoHandle{ 0 };
VS_FIXEDFILEINFO* lpFileInfoBuffer{ nullptr };
UINT uLen{ 0 };

struct Deleter      // Custom delete function for unique_ptr
{
    void operator()(BYTE* ptr) const {
        delete[] ptr;
    }
};

DWORD infoSize = GetFileVersionInfoSizeA("VersionTest.exe", &infoHandle /*ignored*/);

if (infoSize == 0) {
    DWORD err = GetLastError();
    cerr << format("Error: Could not get version info size. ({})", err);
    return -1;
}
cout << format("Version info size: {}\n", infoSize);

std::unique_ptr<BYTE[], Deleter> data(new BYTE[infoSize]);      // create a unique_ptr to an array the size of Version Info that will delete data on exit

if (!GetFileVersionInfoA("VersionTest.exe", 0 /*ignored*/, infoSize, data.get()))
{
    DWORD err = GetLastError();
    cerr << format("Error: Could not get version info. ({})", err);
    return -1;
}
cout << "Version info acquired\n";

VerQueryValueA                  // get version info with https://learn.microsoft.com/en-us/windows/win32/api/winver/nf-winver-verqueryvaluea...
(data.get(),                    // a pointer to the data retrieved by GetFileVersionInfoA
    "\\\\",                     // and a "path" to the version info
    (LPVOID*)&lpFileInfoBuffer, // using a pointer to the buffer that will hold the retrieved version info
    &uLen);                     // with this containing the length of the buffer returned in lpFileInfoBuffer

cout << format("Product version: {}.{}.{}.{}\n",
    HIWORD(lpFileInfoBuffer->dwProductVersionMS),
    LOWORD(lpFileInfoBuffer->dwProductVersionMS),
    HIWORD(lpFileInfoBuffer->dwProductVersionLS),
    LOWORD(lpFileInfoBuffer->dwProductVersionLS));

return 0;

字符串
我绝对不理解VerQueryValueA函数的lpSubBlock参数。

相关问题