0
votes

I'm trying to use the code snippet shown at the end of this page to read multi-language version resource for executable files.

But, for example, when I run the code below for this file:

enter image description here

I get my nCnt as 1 for only one resource, i.e. English.

What am I doing wrong?

LPCTSTR buff = L"path-to\\file.exe";

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

DWORD dwDummy;
DWORD dwSz = GetFileVersionInfoSize(buff, &dwDummy);
if(dwSz > 0)
{
    BYTE* pData = new (std::nothrow)BYTE[dwSz];
    if(pData)
    {
        if(GetFileVersionInfo(buff, NULL, dwSz, pData))
        {
            //Get language info
            UINT ncbSz;
            LANGANDCODEPAGE* pLcp;
            if(VerQueryValue(pData, L"\\VarFileInfo\\Translation", (VOID**)&pLcp, &ncbSz))
            {
                UINT nCnt = ncbSz / sizeof(struct LANGANDCODEPAGE);

                CString strQuery;
                UINT nczBufLn;
                LPCTSTR pDescBuf;

                for(UINT i = 0; i < nCnt; i++)
                {
                    strQuery.Format(L"\\StringFileInfo\\%04x%04x\\FileDescription", 
                        pLcp[i].wLanguage, pLcp[i].wCodePage);
                    if(VerQueryValue(pData, (LPTSTR)strQuery.GetString(), (VOID**)&pDescBuf, &nczBufLn))
                    {
                        wprintf(L"Description%d: %s\n", i, pDescBuf);
                    }
                }
            }
        }

        delete[] pData;
    }
}
1
@RemyLebeau: Well, that is not exactly the same thing. I don't even get to calling VerQueryValue on L"\\StringFileInfo\\%04x%04x\\FileDescription", the call with L"\\VarFileInfo\\Translation" returns size for 1 language when I am expecting 3. That is my issue.c00000fd
I understand the issue. My point is, the translation table is susceptible to human error, and it is a common mistake to code the table incorrectly. You may have 3 languages available but the table only has 1 entry. Use a resource editor to verify. Some resource compilers don't report mismatches like this.Remy Lebeau

1 Answers

1
votes

There are two ways to store multi-language version resources.

The best way is of course to have one resource entry with multiple translation blocks. These will be accessible with VerQueryValue.

The other way is to store multiple resource entries, one for each language. This is the way you store other types of localized resources (bitmaps, strings etc.). EnumResourceLanguages should be able to enumerate them but GetFileVersionInfo will probably just pick the language that matches your thread or UI language.