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

mxg2im7a  于 2024-01-09  发布在  Windows
关注(0)|答案(1)|浏览(197)

此问题在此处已有答案

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错误或警告。我希望输出反映资源文件的内容。

  1. #include <iostream>
  2. #include <format>
  3. #include "resource.h"
  4. using std::cout;
  5. using std::cerr;
  6. using std::endl;
  7. using std::format;
  8. int main() {
  9. struct VersionInfo {
  10. DWORD dwFileVersionMS;
  11. DWORD dwFileVersionLS;
  12. DWORD dwProductVersionMS;
  13. DWORD dwProductVersionLS;
  14. };
  15. // Update the resource identifier to reflect the file name and ID
  16. HRSRC hVersionResource = FindResource(NULL, MAKEINTRESOURCE(1), RT_VERSION);
  17. if (!hVersionResource) {
  18. cerr << "Error: Could not find version resource." << endl;
  19. return -1;
  20. }
  21. HGLOBAL hVersionData = LoadResource(NULL, hVersionResource);
  22. if (!hVersionData) {
  23. cerr << "Error: Could not load version resource." << endl;
  24. return -1;
  25. }
  26. LPVOID pVersionData = LockResource(hVersionData);
  27. if (!pVersionData) {
  28. cerr << "Error: Could not lock version resource." << endl;
  29. return -1;
  30. }
  31. VersionInfo* versionInfo = (VersionInfo*)pVersionData;
  32. // Access and format version information
  33. cout << format("File version: {}.{}.{}.{}\n",
  34. HIWORD(versionInfo->dwFileVersionMS),
  35. LOWORD(versionInfo->dwFileVersionMS),
  36. HIWORD(versionInfo->dwFileVersionLS),
  37. LOWORD(versionInfo->dwFileVersionLS));
  38. cout << format("Product version: {}.{}.{}.{}\n",
  39. HIWORD(versionInfo->dwProductVersionMS),
  40. LOWORD(versionInfo->dwProductVersionMS),
  41. HIWORD(versionInfo->dwProductVersionLS),
  42. LOWORD(versionInfo->dwProductVersionLS));
  43. // Use other version information fields and format with format as needed
  44. FreeResource(hVersionData);
  45. return 0;
  46. }

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

  1. File version: 52.792.86.0
  2. Product version: 95.83.69.86


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

oknwwptz

oknwwptz1#

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

  1. DWORD infoHandle{ 0 };
  2. VS_FIXEDFILEINFO* lpFileInfoBuffer{ nullptr };
  3. UINT uLen{ 0 };
  4. struct Deleter // Custom delete function for unique_ptr
  5. {
  6. void operator()(BYTE* ptr) const {
  7. delete[] ptr;
  8. }
  9. };
  10. DWORD infoSize = GetFileVersionInfoSizeA("VersionTest.exe", &infoHandle /*ignored*/);
  11. if (infoSize == 0) {
  12. DWORD err = GetLastError();
  13. cerr << format("Error: Could not get version info size. ({})", err);
  14. return -1;
  15. }
  16. cout << format("Version info size: {}\n", infoSize);
  17. 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
  18. if (!GetFileVersionInfoA("VersionTest.exe", 0 /*ignored*/, infoSize, data.get()))
  19. {
  20. DWORD err = GetLastError();
  21. cerr << format("Error: Could not get version info. ({})", err);
  22. return -1;
  23. }
  24. cout << "Version info acquired\n";
  25. VerQueryValueA // get version info with https://learn.microsoft.com/en-us/windows/win32/api/winver/nf-winver-verqueryvaluea...
  26. (data.get(), // a pointer to the data retrieved by GetFileVersionInfoA
  27. "\\\\", // and a "path" to the version info
  28. (LPVOID*)&lpFileInfoBuffer, // using a pointer to the buffer that will hold the retrieved version info
  29. &uLen); // with this containing the length of the buffer returned in lpFileInfoBuffer
  30. cout << format("Product version: {}.{}.{}.{}\n",
  31. HIWORD(lpFileInfoBuffer->dwProductVersionMS),
  32. LOWORD(lpFileInfoBuffer->dwProductVersionMS),
  33. HIWORD(lpFileInfoBuffer->dwProductVersionLS),
  34. LOWORD(lpFileInfoBuffer->dwProductVersionLS));
  35. return 0;

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

展开查看全部

相关问题