Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
menu search
person
Welcome To Ask or Share your Answers For Others

Categories

I am really confused with this function. Currently I am successful in retrieving the FileVersion and ProductVersion. Now I want to retrieve more information within the application, like FileDescription and CompanyName.

DWORD dwLen;
VS_FIXEDFILEINFO    *pFileInfo;
UINT                pLenFileInfo;

dwLen = GetFileVersionInfoSize("D:/firefox.exe", NULL);

BYTE *sKey = new BYTE[dwLen];

GetFileVersionInfo("D:/firefox.exe", NULL, dwLen, sKey);

VerQueryValue(sKey, "\", (LPVOID*)&pFileInfo, &pLenFileInfo);

// at now i can retrieve file Version with structure VS_FIXEDFILEINFO

VerQueryValue(sKey, "\StringFileInfo\%04x%09x\FileDescription", (LPVOID*) &pFileInfo, &pLenFileInfo);

delete[] sKey;

cout << pFileInfo;

// it return address buffer `00230428`;

How exactly can I return the FileDescription, like Firefox? What structure is used to retrieve the FileDescription in the 3rd LPVOID parameter? In my code, I pass pFileInfo twice into VerQueryValue().

EDIT:

DWORD dwLen;
    
struct LANGANDCODEPAGE {
        WORD wLanguage;
        WORD wCodePage;
    } *lpTranslate;
    
dwLen = GetFileVersionInfoSize("D:/firefox.exe", NULL);
        
BYTE *sKey = new BYTE[dwLen];
TCHAR *sCompanyName = new char[1024];
        
GetFileVersionInfo("D:/firefox.exe", NULL, dwLen, sKey);
    
VerQueryValue(sKey, "\VarFileInfo\Translation", (LPVOID*)&lpTranslate, &pLenFileInfo);

VerQueryValue(test, "\StringFileInfo\%04x%09x\FileDescription", (LPVOID*)&sCompanyName, &pLenFileInfo);

delete[] sKey;

cout << lpTranslate -> wLanguage;
See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
682 views
Welcome To Ask or Share your Answers For Others

1 Answer

VerQueryValue(test, "\StringFileInfo\%04x%09x\FileDescription",
   (LPVOID*)&sCompanyName, &pLenFileInfo);

The second parameter should be of this format "\StringFileInfo\NxM\FileDescription" where N and M are wLanguage and wCodePage. Following the example in comment section, you can use "%04x%04x" as print format specifier to create a string. Example:

BOOL foo()
{
    const char* filename = "c:\windows\hh.exe";
    int dwLen = GetFileVersionInfoSize(filename, NULL);
    if(!dwLen)
        return 0;

    auto *sKey = new BYTE[dwLen];
    std::unique_ptr<BYTE[]> skey_automatic_cleanup(sKey);
    if(!GetFileVersionInfo(filename, NULL, dwLen, sKey))
        return 0;

    struct LANGANDCODEPAGE {
        WORD wLanguage;
        WORD wCodePage;
    } *lpTranslate;

    UINT cbTranslate = 0;
    if(!VerQueryValue(sKey, "\VarFileInfo\Translation",
        (LPVOID*)&lpTranslate, &cbTranslate))
        return 0;

    for(unsigned int i = 0; i < (cbTranslate / sizeof(LANGANDCODEPAGE)); i++)
    {
        char subblock[256];
        //use sprintf if sprintf_s is not available
        sprintf_s(subblock, "\StringFileInfo\%04x%04x\FileDescription",
            lpTranslate[i].wLanguage, lpTranslate[i].wCodePage);
        char *description = NULL;
        UINT dwBytes;
        if(VerQueryValue(sKey, subblock, (LPVOID*)&description, &dwBytes))
            MessageBox(0, description, 0, 0);
    }
    return TRUE;
}

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
thumb_up_alt 0 like thumb_down_alt 0 dislike
Welcome to ShenZhenJia Knowledge Sharing Community for programmer and developer-Open, Learning and Share
...