Наши проекты:
Журнал · Discuz!ML · Wiki · DRKB · Помощь проекту |
||
ПРАВИЛА | FAQ | Помощь | Поиск | Участники | Календарь | Избранное | RSS |
[44.192.95.161] |
|
Сообщ.
#1
,
|
|
|
Есть файл .SYS. Имеет версию, если посмотреть правой мышой свойства.
Как достать программно эту версию? |
Сообщ.
#2
,
|
|
|
Быть может, вы про то, что этот SYS - всего лишь EXE-шник, с PE32/PE64-заголовком. Тогда можно его открыть, найти поле IMAGE_DIRECTORY_ENTRY_RESOURCE, а там найти подраздел Версия, а там поле ProductVersion.
|
Сообщ.
#3
,
|
|
|
Цитата Славян @ IMAGE_DIRECTORY_ENTRY_RESOURCE Мне бы пример. Гугл результатов по Image_Directory не дает. |
Сообщ.
#4
,
|
|
|
Да просто откройте WinNT.H:
#define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory Добавлено Готового примера у меня нет, так как я делал давно на весьма низком уровне. Схема же такова: 1. Открываем = читаем EXE-шник. 2. Находим начало PE-заголовка. 3. Находим адрес таблицы с ресурсами - IMAGE_DIRECTORY_ENTRY_RESOURCE. 4. Находим смещение в ней раздела с версией. 5. Находим поле-строку ProductVersion/FileVersion. 6. Читаем его-её значение. |
Сообщ.
#5
,
|
|
|
Всё уже давно придумано до нас https://docs.microsoft.com/en-us/windows/wi...-verqueryvaluea
|
Сообщ.
#6
,
|
|
|
В общем, нашел функцию и причесал. Она работает и для SYS, и для EXE. Остальные не проверял. Последний вопрос остался: для чего нужна кодировка asCharset со странным значением 040904B0?
AnsiString asGetGileInfo(AnsiString asFile_Path, int iMode) //0 - ProductName, 1 - FileVersion, 2 - LegalCopyright, 3 - CompanyName. { DWORD dwTemp; //Временная переменная для GetFileVersionInfoSize. DWORD dwSize = GetFileVersionInfoSize(asFile_Path.c_str(), &dwTemp); if (dwSize == 0) return "(GetFileVersionInfoSize не отработала)"; char *cBuffer = ""; //Буфер получения информации для GetFileVersionInfo. cBuffer = (char*)GlobalAlloc(GMEM_FIXED, dwSize); if (GetFileVersionInfo(asFile_Path.c_str(), dwTemp, dwSize, cBuffer) != 0) { char *cValueBuf = ""; //Буфер получения информации для VerQueryValue. UINT uiLen; //Количество параметров файла. Минимум 4. VerQueryValue(cBuffer, "\\VarFileInfo\\Translation", &(void*)cValueBuf, &uiLen); if (uiLen >= 4) { AnsiString asCharSet = IntToHex((int)MAKELONG(*(int*)(cValueBuf+2), *(int*)cValueBuf), 8); if (iMode == 0) { if (VerQueryValue(cBuffer, ("\\StringFileInfo\\" + asCharSet + "\\ProductName").c_str(), &(void*)cValueBuf, &uiLen) != 0) return cValueBuf; else return "(не удалось получить ProductName)"; } else if (iMode == 1) { if (VerQueryValue(cBuffer, ("\\StringFileInfo\\"+asCharSet+"\\FileVersion").c_str(), &(void*)cValueBuf, &uiLen) != 0) return cValueBuf; else return "(не удалось получить FileVersion)"; } else if (iMode == 2) { if (VerQueryValue(cBuffer, ("\\StringFileInfo\\"+asCharSet+"\\LegalCopyright").c_str(), &(void*)cValueBuf, &uiLen) != 0) return cValueBuf; else return "(не удалось получить LegalCopyright)"; } else if (iMode == 3) { if (VerQueryValue(cBuffer, ("\\StringFileInfo\\"+asCharSet+"\\CompanyName").c_str(), &(void*)cValueBuf, &uiLen) != 0) return cValueBuf; else return "(не удалось получить CompanyName)"; } } else return "(uiLen < 4)"; } else return "GetFileVersionInfo не отработала"; GlobalFree(cBuffer); } |
Сообщ.
#7
,
|
|
|
Посмотри эту статью.
Никаких разборок с кодировками. Единственное - нужно определиться какую версию использовать ansi или unicode. Хотя выбор очевиден. |
Сообщ.
#8
,
|
|
|
Цитата Сергей85 @ Ресурс версии может содержать разные строковые блоки одинакового назначения, различающиеся языком описания. Старший WORD определяет кодовую страницу (0x0409 – U.S. English), младший – способ кодирования символов (0x04B0 – юникод). По идее, чтобы предоставить эту инфу пользователю, ты должен определить предпочтительную им кодовую страницу и искать соответствующие ей строковые блоки, декодируя их указанным способом кодирования. Если не нашлось... зависит от предпочтений пользователя. Или твоей программы. Последний вопрос остался: для чего нужна кодировка asCharset со странным значением 040904B0? |