Destiny
|
Posted: Tue Oct 15, 2024 00:57 Post subject: |
|
|
Понадобилось тут как-то нам внедрить свой блок VERSIONINFO в свою программу.
Причем чтобы и на русском и на английском было видно, когда смотришь в Свойствах-Подробно в Проводнике...
И вот после внедрения блока и проверки/просмотре в вашем плагине и в плагине fileinfo и после
многократного перечитывания https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource
появились вопросы, замечания?/указания на возможные баги?
Итак, всё началось с создания ресурса. Замечаем на фотке сразу: какие поля есть в редакторе и какие их значения.
И вот что есть у вас:
Name: в редакторе "Узел версии", в плагине "1".
Язык: в редакторе указан Русский, в плагине "Английский"...
Вопрос - КАК такое может быть? Далее - а откуда ВООБЩЕ возможна тут, на этом уровне представления данных, эта
информация о некоей кодовой странице? Она применяется к чему? Ко всему блоку???
В ссылке /learn.microsoft.com ни о чем таком нет инфы.
Да и для чего указывается 0 (ANSI)? В ресурсах же IDE мы видим, что указывается ЛИШЬ и ТОЛЬКО сам язык. Русский и .
Если информации нет для поля (а само поле вы убирать не хотите для стабильности GUI) - значит надо указать фразу
"неприменимо" или "нет данных" - в зависимости от обстоятельств.
Кстати, а что такое этот Тип 16? Вроде тип в этой структуре согласно справке константа 1 - и означающая, что это блок
с VERSIONINFO. А у вас что тут подразумевается? Вообще - какие тогда типы с какими константами вы знаете/выводите?
Теперь открываем файл в плагине FileInfo и видим:
Language : Английский (США) (0x409)
Character Set : 1200 (ANSI - Unicode (BMP of ISO 10646)) (0x4B0)
Язык тоже Инглиш. И тут же уже хотя бы 1200! а не `0` какой-то - как у вас. И это правильный вывод - т.к. мы оформили
соответствующие блоки строковых данных для двух языков в Юникодной кодировке. Пример оформления см. ниже в виде
куска кода из *.rc файла.
А вот касательно 0... Есть файл AkelPad64.exe. Так для него FileInfo показывает-таки этот 0, но
это показ в форме строки: Not referenced (0x0)! Т.е. именно в том ключе, как я выше и предлагал:
"Если информации нет для поля (а само поле вы убирать не хотите для стабильности GUI) - значит надо указать фразу
"неприменимо" или "нет данных" - в зависимости от обстоятельств."
А ваш же плагин по-прежнему пишет (0) (ANSI - кириллица) - явно баг получается.
Далее. Помните, выше я сказал, что нам надо двуязычность этого ресурса? RU + EN.
Казалось бы в справке четко указано: надо сделать в структуре StringFileInfo столько блоков StringTable, сколько
языков надо охватить. Причем в начале блока указывается "lang-charset", который содержит инфу о текущем языке.
Хорошо, в файле ресурсов *.rc так и сделали.
Code: |
//040904B0 = 0x0409 (1033, U.S. English) + 0x04B0 (1200, Unicode) or 0x04E4 (1252, Multilingual, Western Europe)
#ifdef UNICODE
BLOCK "040904B0"
#else
BLOCK "040904E4"
#endif
BEGIN
VALUE "CompanyName", VER_COMPANYNAME_STR
VALUE "FileDescription", VER_FILEDESCRIPTION_STR
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_STR
VALUE "LegalTrademarks", VER_LEGALTRADEMARKS_STR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_STR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
//041904E3 = 0x0419 (1049, Russian) + 0x04B0 (1200, Unicode) or 0x04E3 (1251, Cyrillic)
#ifdef UNICODE
BLOCK "041904B0"
#else
BLOCK "041904E3"
#endif
BEGIN
VALUE "CompanyName", VER_COMPANYNAME_RUSTR
VALUE "FileDescription", VER_FILEDESCRIPTION_RUSTR
VALUE "FileVersion", VER_FILEVERSION_STR
VALUE "InternalName", VER_INTERNALNAME_STR
VALUE "LegalCopyright", VER_LEGALCOPYRIGHT_RUSTR
VALUE "LegalTrademarks", VER_LEGALTRADEMARKS_RUSTR
VALUE "OriginalFilename", VER_ORIGINALFILENAME_STR
VALUE "ProductName", VER_PRODUCTNAME_RUSTR
VALUE "ProductVersion", VER_PRODUCTVERSION_STR
END
END |
Вроде всё правильно. Теперь надо указать доступность этих самых языков. Вроде как согласно справке для
этого используется следующий блок:
Code: |
BEGIN
#ifdef UNICODE
VALUE "Translation", 0x0409, 0x04B0, 0x0419, 0x04B0
#else
VALUE "Translation", 0x0409, 0x04E4, 0x0419, 0x04E3
#endif
END |
Ок, собран проект, открыт файл в вашем плагине и внутри блока StringFileInfo корректно видны
два суб-блока StringTable. Это StringTable 0 и StringTable 1. Внутри них видны корректные записи.
И это супер плюс. А вот что же насчет блока VarFileInfo для Translation?
Code: |
VarFileInfo
{
Translation 0: 0x0409, 0x04B0
} |
А вот это всё, что видит плагин. Т.е. попытка увидеть не одну пару - есть, ибо в названии
по аналогии с описанными выше блоками есть `0` суффикс. Т.е. типа первую пару плагин
получается вывел, ну а где же тогда вторая пара?
Code: |
VarFileInfo
{
Translation 0: 0x0409, 0x04B0
Translation 1: 0x0419, 0x04B0
} |
Вот почему вывод не такой? Ок, для сравнения открываем FileInfo. НО там нет вообще
такого же вывода. Есть подозрение, что за это должен был бы отвечать вывод типа вот
этого всё же существующего:
Quote: | Language : Английский (США) (0x409)
Character Set : 1200 (ANSI - Unicode (BMP of ISO 10646)) (0x4B0) | Ибо он-то есть.
НО! Так ну нет же всё же рядом второго! Т.е. нет вывода по логике вот такого:
Quote: | Language : Английский (США) (0x409)
Character Set : 1200 (ANSI - Unicode (BMP of ISO 10646)) (0x4B0)
Language : Русский(Россия) (0x419)
Character Set : 1200 (ANSI - Unicode (BMP of ISO 10646)) (0x4B0) |
Тогда открываем для сравнения утилиту PEAnatomist:
Code: |
"VarFileInfo" {
"Translation", 0x0409, 0x04B0, 0x0419, 0x04B0
} |
Т.е. она в состоянии найти была и увидеть эти две пары данных... Причем вывод идет так, как
это писано в справке M$! А выше вот "в два блока - один над другим" - это было как бы мои
предположения лишь: мол, а хотя бы разве не "так" надо бы выводить инфу? НО если верить
справке - нет. Надо именно как в этой утилите - подряд через запятые подряд.
Значит всё же это большой баг в вашем плагине (как и в FileInfo)?
Далее идет более сложный вопрос. По идее полностью он от вас не зависит. Но может просто
огромная практика разбора ресурсов поможет подсказать нам выход из положения...
Ибо, еще раз - помним же про то, что нам надо двуязычность этого ресурса? RU + EN.
Так вот, теперь открыв в Проводнике меню, вызвав оттуда Свойства и открыв вкладку Подробно
мы увидели, что Все строки на инглише.. Но как? В пункте "Язык" вроде как четко считывается:
"Английский (США), Русский (Россия)"! Т.е. на русской локали ОС мы должны были бы увидеть
и все строки на русском. Переключаем на Инглиш всю ОС - всё по прежнему на инглише.
Возвращаемся на Русский - но ничего не исправилось. Все строки по прежнему на инглише.
И тут под руку случайно попадается файл SpellCheck.dll
И на нем эта двуязычность работает!!!!! На Обеих локалях ОС - на русском и на английском.
Открываем в вашем плагине этот файл, чтобы проверить, что там и как...
А там аж три ресурса VERSIONINFO! ХОТЯ в справке от мелкомягких явно пишется что она одна на весь файл!
НО допустим.. Может что-то изменилось...
Но опять-таки смотрим на ту инфу, что показывает плагин. Видите опять про кодовую страницу?
ОПЯТЬ там почему-то лишь 0, ХОТЯ в блоке этой VERSIONINFO структуры явно указан UNICODE!
Code: |
StringFileInfo
{
StringTable 0 (0x0419, 0x04b0)
{
Comments: Юникод версия
FileDescription: Проверка орфографии в AkelPad на базе Hunspell
FileVersion: 1.3.0.5
InternalName: SpellCheck.dll
OriginalFilename: SpellCheck.dll
ProductName: SpellCheck (x64)
ProductVersion: 1.3.0.5
}
}
VarFileInfo
{
Translation 0: 0x0419, 0x04B0
}
|
Вот что мы явно видим: 0x04b0 = 1200 = UNICODE! Ну явно же ошибка вывода данных в плагине!
Так же читаем поле ИМЯ и его значение: "1049 (Русский (Россия))". И вопрос - а ГДЕ это можно было
менять? Мы же в начале показали, что ИМЯ в самом редакторе ресурсов задано как константная строка
"Узел версии"!
И более ничего подходящего под имя в официальном редакторе нет! Так откуда и как в SpellCheck.dll
смогли загнать это имя? ИЛИ же по другому спросим - а откуда плагин умудряется читать это значение?
Из какого поля и какой официальной структуры, описанной на уровне сайта мелкомягких:
https://learn.microsoft.com/en-us/windows/win32/menurc/versioninfo-resource?
Ну и все же - как можно объяснить такой казус - как 3 структуры VERSIONINFO в одном файле?
Разве это нормально и часто встречается? Т.е. только так можно по аналогии и нам добавить
двуязычность вывода строк из структуры VERSIONINFO?
Мне думается, что вряд ли можно, ибо если открыть вкладку ИНФО вашего плагина на этом файле, то
к выводу подаются лишь строки для:
Quote: |
Комментарии,"Юникод версия"
Описание файла,"Проверка орфографии в AkelPad на базе Hunspell"
Версия файла,1.3.0.5
Внутреннее имя,SpellCheck.dll
Исходное имя файла,SpellCheck.dll
Название продукта,"SpellCheck (x64)"
Версия продукта,1.3.0.5
Язык,"0x0419 (1049) (Русский (Россия))"
Кодовая страница,"0x04B0 (1200)" |
И всё! Хоть и есть ТРИ структуры - плагин почему-то показывает данные лишь по одной! А вот если смотреть
наш файл, сделанный по справке от М$, то на этой вкладке корректно видны два суб-блока вида StringTable.
Внутри них видны корректные записи по аналогии с перечисленными выше.
Last edited by Destiny on Sat Oct 26, 2024 16:54; edited 3 times in total |
|