【问题标题】:How to traverse a multi-language version resource?如何遍历多语言版本资源?
【发布时间】:2020-09-06 06:01:48
【问题描述】:

我正在尝试使用代码 sn-p 显示at the end of this page 来读取可执行文件的多语言版本资源。

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

我的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;
    }
}

【问题讨论】:

  • @RemyLebeau:嗯,这不完全一样。我什至没有在L"\\StringFileInfo\\%04x%04x\\FileDescription" 上调用VerQueryValue,当我期待3 时,使用L"\\VarFileInfo\\Translation" 的调用返回1 语言的大小。这是我的问题。
  • 我理解这个问题。我的观点是,翻译表容易受到人为错误的影响,并且错误地编码表是一个常见的错误。您可能有 3 种语言可用,但该表只有 1 个条目。使用资源编辑器进行验证。一些资源编译器不会报告这样的不匹配。

标签: c++ winapi modern-ui


【解决方案1】:

多语言版本资源有两种存储方式。

最好的方法当然是一个资源条目带有多个翻译块。这些将可通过VerQueryValue 访问。

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

【讨论】:

  • 我明白了。所以你说的是我的选择之一是手动解析 PE 标头。 (我没有EnumResourceLanguagesHMODULE 句柄。)
  • 如果这是某种 PE 版本查看器/实用程序,并且您想支持所有版本类型,那么是的,您必须进行一些手动解析。您也许可以在非 Win9x 系统上欺骗 VerQueryValueW 读取原始资源数据,但这有点冒险,因为它可能会在 GetFileVersionInfo 中做一些额外的工作来处理数据。
  • 不,我需要它与 Windows 95 兼容。
  • 那你必须自己解析,32位版本的资源是以Unicode存储的,Win9x上的API使用额外的数据来存储翻译后的字符串。
  • 是的,伙计,我在开玩笑说 Win95。但是是的,否则看起来我需要手动解析它。 (我刚刚进入GetFileVersionInfo*VerQueryValue API,除了内部引发和静音各种异常之外,它们效率非常低。每个API基本上都调用LoadLibraryEx将文件映射到内存然后释放它。即使所有你需要的是资源的大小。)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-12-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-08-11
相关资源
最近更新 更多