C++ 如何遍历多语言版本资源?

C++ 如何遍历多语言版本资源?,c++,winapi,modern-ui,C++,Winapi,Modern Ui,我试图使用显示的代码片段来读取可执行文件的多语言版本资源 但是,例如,当我为此文件运行下面的代码时: 我的nCnt作为1仅用于一种资源,即英语 我做错了什么 LPCTSTR buff = L"path-to\\file.exe"; struct LANGANDCODEPAGE { WORD wLanguage; WORD wCodePage; } *lpTranslate; DWORD dwDummy; DWORD dwSz = GetFileVersionInfoSize(buf

我试图使用显示的代码片段来读取可执行文件的多语言版本资源

但是,例如,当我为此文件运行下面的代码时:

我的
nCnt
作为
1
仅用于一种资源,即英语

我做错了什么

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;
    }
}
LPCTSTR buff=L“指向\\file.exe的路径”;
结构LANGANDCODEPAGE{
词汇语言;
单词wCodePage;
}*翻译;
德沃德;
DWORD dwSz=getFileVersionInfo(buff,&dwDummy);
如果(dwSz>0)
{
字节*pData=新的(std::nothrow)字节[dwSz];
如果(pData)
{
if(GetFileVersionInfo(buff、NULL、dwSz、pData))
{
//获取语言信息
UINT ncbSz;
LANGANDCODEPAGE*pLcp;
if(VerQueryValue(pData,L“\\VarFileInfo\\Translation”,(VOID**)&pLcp和ncbSz))
{
UINT nCnt=ncbSz/sizeof(结构语言和代码页);
CString-strQuery;
UINT-nczBufLn;
LPCTSTR-pDescBuf;
对于(UINT i=0;i
存储多语言版本资源有两种方法

当然,最好的方法是使用一个资源条目和多个翻译块。可通过
VerQueryValue
访问这些文件


另一种方法是存储多个资源条目,每种语言一个。这是存储其他类型的本地化资源(位图、字符串等)的方式
EnumResourceLanguages
应该能够枚举它们,但是
GetFileVersionInfo
可能只会选择与您的线程或UI语言匹配的语言。

@RemyLebeau:嗯,这不完全是一回事。我甚至无法在
L“\\StringFileInfo\\%04x%04x\\FileDescription”
上调用
VerQueryValue
,使用
L“\\VarFileInfo\\Translation”
的调用在我期望3种语言时返回1种语言的大小。这是我的问题,我理解这个问题。我的观点是,翻译表容易受到人为错误的影响,错误地编码表是一种常见的错误。您可能有3种可用语言,但该表只有1个条目。使用资源编辑器进行验证。有些资源编译器不会报告这样的不匹配。我明白了。所以你的意思是,我的选择之一是手动解析PE头。(我没有
EnumResourceLanguages
HMODULE
句柄)如果这是某种PE版本查看器/实用程序,并且您希望支持所有版本类型,那么是的,您必须进行一些手动解析。您可能能够在非Win9x系统上欺骗
VerqueryValue
读取原始资源数据,但这有点冒险,因为它可能在
GetFileVersionInfo
中做一些额外的工作来处理数据。不,我需要它与Windows 95兼容。然后您必须解析自己,32位版本资源存储在Unicode中,Win9x上的API使用额外的数据来存储翻译的字符串。是的,伙计,我在开Win95的玩笑。但是是的,否则看起来我需要手动解析它。(我刚刚进入了
GetFileVersionInfo*
VerQueryValue
API,除了在内部引发和禁用各种异常外,它们的效率非常低。每个API基本上都调用
LoadLibraryEx
将文件映射到内存中,然后释放它。即使您只需要资源的大小。)