Не удается прочитать FileVersionInfo с несоответствием кодовой страницы
У меня есть некоторый разумно опробованный и протестированный код, который использует вызовы API Windows для чтения строк FileVersionInfo, например "FileVersion" и "CompanyName".
Я обнаружил, что это не удалось с одной конкретной сторонней DLL. Проблема, кажется, заключается в следующем:
Чтение \VarFileInfo\Translation
ценность, я получаю 040904B0
(Американский английский, Unicode). Но когда я тогда пытаюсь позвонить VerQueryValue
на \StringFileInfo\040904B0\CompanyName
, он возвращает ложь.
Но настройка кода для использования кодовой страницы ANSI Windows Latin-1 работает: \StringFileInfo\040904E4\CompanyName
,
Таким образом, кодовая страница в таблице строк не соответствует \VarFileInfo\Translation
значение.
В соответствии с примером ресурса в нижней части документации по ресурсу MSDN VERSIONINFO, это уместно!
Учитывая это, могу ли я использовать опубликованные API-интерфейсы VersionInfo, чтобы правильно прочитать строки для этого файла, не "угадывая" кодовую страницу?
1 ответ
К сожалению VERSIONINFO
структура, скомпилированная из файла ресурсов, позволяет вам определять языки, которых нет в строковом блоке, и строковые блоки, которые не имеют записи в языковой таблице. Другими словами, структура не проверена. Как упоминает Jonathan Potter в комментариях, лучше всего при работе с произвольной библиотекой использовать эвристический поиск блока строк, который лучше всего подходит для вашего приложения.
В вашем случае, однако, вы используете библиотеки VLC, которые в настоящее время определяют информацию о своей версии следующим образом: (обрезается, чтобы не занимать половину страницы)
BEGIN
BLOCK "StringFileInfo"
BEGIN
BLOCK "040904E4"
BEGIN
(...)
END
END
BLOCK "VarFileInfo"
BEGIN
VALUE "Translation", 0x409, 1200
END
END
Как вы видите, язык в блоке перевода - en-us CP1200 (UTF-16LE), но строковый блок помечен en-us CP1252 (ANSI Latin 1). Как ни странно, информация для основного исполняемого файла верна, а информация почти идентична.
Remy Lebeau отправил отчет об ошибке для этой проблемы, а я отправил патч.
По состоянию на 24 июня 2016 года патч был принят и перенесен в ветку 2.2.