Версия для печати
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум на Исходниках.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_ENTRY_RESOURCE


Мне бы пример. Гугл результатов по 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 @
Последний вопрос остался: для чего нужна кодировка asCharset со странным значением 040904B0?
Ресурс версии может содержать разные строковые блоки одинакового назначения, различающиеся языком описания. Старший WORD определяет кодовую страницу (0x0409 – U.S. English), младший – способ кодирования символов (0x04B0 – юникод). По идее, чтобы предоставить эту инфу пользователю, ты должен определить предпочтительную им кодовую страницу и искать соответствующие ей строковые блоки, декодируя их указанным способом кодирования. Если не нашлось... зависит от предпочтений пользователя. Или твоей программы.

Powered by Invision Power Board (https://www.invisionboard.com)
© Invision Power Services (https://www.invisionpower.com)