簡體   English   中英

如何使用 VerQueryValue 獲取 FileDescription(讓示例工作)?

[英]How to get FileDescription with VerQueryValue (getting the example to work)?

我正在嘗試使用 WinAPI function VerQueryValue獲取文件的各種屬性,如其“詳細信息”選項卡中所示。 我已成功使用此 function 來獲取非字符串版本信息VS_FIXEDFILEINFO ,但無法使函數文檔底部顯示的示例正常工作。

該示例實際上並不完整,因為它忽略了其他相關功能的使用以及使用 function 所需的一些緩沖區的結構,因此我已盡我所能填補空白並更改了一些中間部分使用 C++ SL 的步驟,因為這最終是我需要使用的語言:

#include <iostream>
#include <iomanip>
#include "sstream"
#include "Windows.h"
#pragma comment(lib, "Version.lib")

int ReadOutFileDescriptions(std::wstring filename)
{
    LPBYTE lpBuffer = NULL;
    DWORD  verHandle, verSize = GetFileVersionInfoSize(filename.c_str(), &verHandle);

    if (verSize != NULL)
    {
        LPSTR verData = new char[verSize];

        if (GetFileVersionInfo(filename.c_str(), verHandle, verSize, verData))
        {
            UINT cbTranslate;

            // Structure used to store enumerated languages and code pages.
            struct LANGANDCODEPAGE {
                WORD wLanguage;
                WORD wCodePage;
            } *lpTranslate;

            // Read the list of languages and code pages.
            VerQueryValue(verData, TEXT("\\VarFileInfo\\Translation"), (LPVOID*)&lpTranslate, &cbTranslate);

            // Read the file description for each language and code page.
            for (ULONGLONG i = 0; i < (cbTranslate / sizeof(struct LANGANDCODEPAGE)); i++)
            {
                std::wostringstream ss; ss << std::setfill(L'0') << std::hex;
                ss << std::setw(4) << lpTranslate[i].wLanguage;
                std::wstring langS = ss.str();
                ss.str(std::wstring());
                ss << std::setw(4) << lpTranslate[i].wCodePage;
                std::wstring codeS = ss.str();
                std::wstring subBlock = L"\\StringFileInfo\\" + langS + codeS + L"\\FileDescription";

                // Retrieve file description for language and code page "i".
                WCHAR descBuffer[50];
                LPVOID lpBuffer = &descBuffer;
                UINT bufferSize;
                VerQueryValue(verData, subBlock.c_str(), &lpBuffer, &bufferSize);
                
                std::cout << bufferSize << '\n' << descBuffer; 
            }
        }

        delete[] verData;
    }

    return 0;
}

int main(int argc, char* argv[])
{
    ReadOutFileDescriptions(L"MyFile.exe");
    return 0;
}

我對 WinAPI 及其類型定義只有一點經驗,我的 C 有點生銹,所以我確定我只是設置/使用不正確的緩沖區等。

打印的緩沖區大小是正確的( MyFile.exe的描述長度 + null 字符的長度)所以我知道 function 得到了正確的值,但實際打印的值只是一系列十六進制字符,大多數可能是地址。

我究竟做錯了什么?

編輯(答案):感謝@dxiv,我意識到我沒有完全理解 VerQueryValue 的“結果”參數(lplpBuffer)是如何在內部和 function 返回之后使用的。

將循環的結尾更改為以下內容可以達到我想要的結果:

//WCHAR descBuffer[50] Not required, the function doesn't utilize a user made buffer
LPVOID lpBuffer;
UINT bufferSize;

VerQueryValue(verData, subBlock.c_str(), &lpBuffer, &bufferSize); // lpBuffer is reassigned here
std::wstring fileDescription((const TCHAR*)lpBuffer); // Create std::string from C style string (char*) that lpBuffer now points to
std::wcout << bufferSize << '\n' << fileDescription;
VerQueryValue(verData, subBlock.c_str(), &lpBuffer, &bufferSize);

std::cout << bufferSize << '\n' << descBuffer; 

一旦VerQueryValue返回, lpBuffer不再指向descBuffer ,而是指向調用內部分配的不同緩沖區。 返回的字符串此時位於(const TCHAR *)lpBuffer處。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM