Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате |
Форум на Исходниках.RU > Borland C++ Builder/Turbo C++ Explorer > Как узнать версию любого файла, доступную в его свойствах? |
Автор: Сергей85 24.07.19, 15:54 |
Есть файл .SYS. Имеет версию, если посмотреть правой мышой свойства. Как достать программно эту версию? |
Автор: Славян 24.07.19, 16:18 |
Быть может, вы про то, что этот SYS - всего лишь EXE-шник, с PE32/PE64-заголовком. Тогда можно его открыть, найти поле IMAGE_DIRECTORY_ENTRY_RESOURCE, а там найти подраздел Версия, а там поле ProductVersion. |
Автор: Сергей85 24.07.19, 17:21 |
Мне бы пример. Гугл результатов по Image_Directory не дает. |
Автор: Славян 24.07.19, 17:55 |
Да просто откройте WinNT.H: <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory Добавлено Готового примера у меня нет, так как я делал давно на весьма низком уровне. Схема же такова: 1. Открываем = читаем EXE-шник. 2. Находим начало PE-заголовка. 3. Находим адрес таблицы с ресурсами - IMAGE_DIRECTORY_ENTRY_RESOURCE. 4. Находим смещение в ней раздела с версией. 5. Находим поле-строку ProductVersion/FileVersion. 6. Читаем его-её значение. |
Автор: Gonarh 25.07.19, 01:28 |
Всё уже давно придумано до нас https://docs.microsoft.com/en-us/windows/wi...-verqueryvaluea |
Автор: Сергей85 29.07.19, 15:08 |
В общем, нашел функцию и причесал. Она работает и для SYS, и для EXE. Остальные не проверял. Последний вопрос остался: для чего нужна кодировка asCharset со странным значением 040904B0? <{CODE_COLLAPSE_OFF}><{CODE_WRAP_OFF}> 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); } |
Автор: JoeUser 29.07.19, 15:22 |
Посмотри эту статью. Никаких разборок с кодировками. Единственное - нужно определиться какую версию использовать ansi или unicode. Хотя выбор очевиден. |
Автор: Qraizer 29.07.19, 16:06 |
Цитата Сергей85 @ Ресурс версии может содержать разные строковые блоки одинакового назначения, различающиеся языком описания. Старший WORD определяет кодовую страницу (0x0409 – U.S. English), младший – способ кодирования символов (0x04B0 – юникод). По идее, чтобы предоставить эту инфу пользователю, ты должен определить предпочтительную им кодовую страницу и искать соответствующие ей строковые блоки, декодируя их указанным способом кодирования. Если не нашлось... зависит от предпочтений пользователя. Или твоей программы. Последний вопрос остался: для чего нужна кодировка asCharset со странным значением 040904B0? |