Научно-исследовательская лаборатория систем ЧПУ
Научно-исследовательская лаборатория систем ЧПУ

Поиск по сайту:
 

Расписание курсов "Программирование SINUMERIK 810D/840D/840Di"



Информация о версии файла

Авторы: Козак Н.В.
МГТУ "СТАНКИН"
Бабак Д.А.
МГТУ "СТАНКИН"
Опубликовано: 14.05.2003
Версия текста: 1.0

 

Введение

В процессе установки программ часто требуется получить информацию о версии или другую сопутствующую информацию из области ресурсов файла. Для этого в MSDN рекомендуется использовать следующие функции: GetFileVersionInfoSize, GetFileVersionInfo, VerQueryValue, VerLanguageName. Данная статья содержит описание алгоритмов получения доступа к информации, хранящейся в области ресурсов файла, в том числе доступа к версии файла. В качестве языка использовался С++.

Структура VS_VERSIONINFO

Основную информацию о версии файла содержит структура VS_VERSIONINFO. Это корневая структура, которая содержит все остальные структуры о версии файла. Формат данной структуры представлен на Рис. 1.

ПолеНазначение
wLength Длина структуры
wValueLength Длина члена структуры Value
wType Идентификатор типа данных в структуре. Значение 1 показывает, что в структуре содержатся текстовые данные, 0 – бинарные данные.
szKey[ ] Постоянная строка “VS_VERSION_INFO” служит для идентификации типа структуры.
Padding1[ ] Служит для выравнивания по 32 битной границе структуры Value.
Value Содержит структуру VS_FIXEDFILEINFO.
Padding2[ ] Служит для выравнивания по 32 битной границе структуры Children[ ].
Children Содержит массив структур StringFileInfo и/или VarFileInfo.
Табл. 1. Назначение полей структуры VS_VERSIONINFO

 

Структура VS_FIXEDFILEINFO определяет языконезависимую область информации о версии.

 


Рис. 1 Формат структуры VS_VERSIONINFO

 

ПолеНазначение
dwSignature Поле содержит постоянное значение “ 0xFEEFO4BD ” и служит вместе с полем szKey структуры VS_VERSIONINFO для нахождения начала структуры VS_FIXEDFILEINFO в файле.
dwStrucVersion Определяет версию структуры.
dwFileVersionMS Определяет первые два числа версии файла. Полное значение версии состоит из двух 32 битных значений, или четырёх 16 битных целых чисел. Например, "FILEVERSION 3,10,0,61" переводится в два двойных слова (DWORD): 0x0003000a и 0x0000003d;
dwFileVersionLS Определяет последние два числа версии файла.
dwProductVersionMS Аналогично версии файла и полям dwStrucVersion и dwFileVersionMS определяет версию продукта, её первые два числа.
dwProductVersionLS Определяет последние два числа версии продукта.
dwFileFlagsMask Содержит “маску битов”, которая определяет значащие биты для dwFileFlags.
dwFileFlags Содержит “маску битов”, которая определяет булевы атрибуты файла. Может содержать комбинацию из следующих значений: VS_FF_DEBUG, VS_FF_INFOINFERRED, VS_FF_PATCHED, VS_FF_PRERELEASE, VS_FF_PRIVATEBUILD, VS_FF_SPECIALBUILD – они описывают назначение и специфику данного файла.
dwFileOS Описывает операционную систему, для которой предназначен данный файл. Может иметь одно из следующих значений: VOS_DOS, VOS_NT, VOS__WINDOWS16, VOS__WINDOWS32, VOS_OS216, VOS_OS232, VOS__PM16, VOS__PM32, VOS_UNKNOWN.
dwFileType Описывает тип файла (.dll, .ocx, .exe, …)
dwFileSubtype Описывает подтип файла.
dwFileDateMS, dwFileDateLS Определяют 64 битное значение даты создания файла.
Табл. 2. Назначение полей структуры VS_FIXEDFILEINFO

 

Поле Children[], структуры VS_VERSIONINFO, содержит список языкозависимых блоков информации о версии. Каждый блок представлен в виде структуры StringFileInfo.

ПолеНазначение
wLength Длина структуры, включает в себя длинны всех подструктур.
wValueLength Нулевое значение.
wType Идентификатор типа данных в структуре.
szKey[ ] Содержит постоянное значение "StringFileInfo" в формате “Unicode string”.
Padding[ ] Выравнивание по 32 битной границе члена структуры StringFileInfo Children[].
Children[] Содержит подструктуры StringTable, каждая из которых создана для своего языка и номера кодовой страницы.
Табл. 3. Назначение полей структуры StringFileInfo

 

В свою очередь StringTable содержит структуры String, каждая из которых описывает пару значений (ключ, значение). Ключ задается полем szKey, а значение – полем Value структуры String. Ключ может быть одним из следующих:

ПолеНазначение
Comments Комментарии.
CompanyName Имя компании.
FileDescription Идентификатор типа данных в структуре.
FileVersion Версия файла.
InternalName Внутреннее имя файла.
LegalCopyright Содержит copyright файла.
LegalTrademarks Торговая марка.
OriginalFilename Действительное имя файла.
PrivateBuild Описание специальной информации о сборке файла.
ProductName Имя продукта.
ProductVersion Версия продукта.
SpecialBuild Описываются отличия от какой либо другой (например, базовой) версии файла.
Табл. 4 Назначение ключей структуры String

 

В поле Children[], структуры VS_VERSIONINFO может содержаться один языконезависимый блок. Этот блок представляет собой структуру VarFileInfo. Она содержит в себе список языков, который представлен в подструктуре Var в виде поля Value. Поля VarFileInfo следующие:

ПолеНазначение
wLength Длина структуры, включая длину вложенной структуры.
wValueLength Нулевое поле.
wType Идентификатор типа данных в структуре.
szKey[ ] Содержит постоянное значение "VarFileInfo" в формате “Unicode string”.
Padding[ ] Выравнивание по 32 битной границе члена структуры VarFileInfo Children[].
Children[] Указывает на одну или несколько структур типа Var.
Табл. 5. Назначение полей структуры VarFileInfo

Структура Var может содержать произвольные бинарные данные, хотя, обычно структура используется только для хранения списка пар (ключ языка, кодовая страница) в поле Value[], что однозначно идентифицируется строкой “Translation” формате Unicode, записанной в поле szKey данной структуры.

ПолеНазначение
wLength Длина структуры.
wValueLength Длина члена структуры Value.
wType Идентификатор типа данных в структуре.
szKey[ ] Содержит постоянное значение "Translation" в формате “Unicode string”.
Padding[ ] Выравнивание по 32 битной границе члена Value[].
Value[] Содержит массив пар (идентификатор языка и номер кодовой страницы), который может содержать одно или более значений.
Табл. 6. Назначение полей структуры Var

Однозначно идентифицировать структуру StringTable или VarFileInfo в поле Children[] структуры VS_VERSIONINFO, можно по значению szKey т.к. типы данных первых 3-х полей в этих структурах одинаковы. Имея их и зная постоянный размер структуры VS_FIXEDFILEINFO и полей, предшествующих полю Children[] в VS_VERSIONINFO, возможно установить указатель на начало поля szKey (неважно какой структуры StringTable или VarFileInfo) и сравнить его значение.

Пример чтения полей структуры VS_FIXEDFILEINFO

Далее приводится фрагмент программы для чтения содержимого языконезависимой информации в файле.

Общие переменные, необходимые для работы:

char buff[128];                  // временные буферы для работы алгоритма
            char szResourceX [80];
            char *pszResourceX = szResourceX;
            

На первом этапе необходимо получить размер структуры VS_VERSIONINFO для резервирования памяти, для чего требуется передать функции GetFileVersionInfoSize строку с полным путём и именем файла, информация о версии которого нам необходима.

LPDWORD lpdwHandleToZero = NULL;
            DWORD dwSizeFVerInf;             // размер главной структуры
            CString DllName = “Dll.dll”;	// имя файла
            dwSizeFVerInf = ::GetFileVersionInfoSize((LPTSTR)(LPCTSTR)DllName, lpdwHandleToZero);
            

 

Далее получаем указатель на структуру VS_VERSIONINFO, используя полученный её размер для распределения памяти.

LPVOID lpFixedFileInf;           // указатель на структуру VS_VERSIONINFO
            lpFixedFileInf = new char[dwSizeFVerInf];
            BOOL bRet = ::GetFileVersionInfo(
            (LPTSTR)(LPCTSTR)DllName,
            NULL,
            dwSizeFVerInf,
            lpFixedFileInf);
            if(bRet == FALSE)
            {
            // обработка ошибки
            }
            

После этого получаем указатель на VS_FIXEDFILEINFO. Для этого передаём в функцию VerQueryValue вторым параметром значение “//”. Третьим параметром передаем указатель на структуру VS_FIXEDFILEINFO. В четвёртом параметре функция возвращает длину в символах данной структуры.

VS_FIXEDFILEINFO *pFixedFileInfo; // указатель на структуру VS_FIXEDFILEINFO
            UINT uLen = 0;
            bRet = VerQueryValue(
            (const LPVOID)lpFixedFileInf,
            "",
            (LPVOID *) (&pFixedFileInfo),
            &uLen);
            if(bRet == FALSE)
            {
            // обработка ошибки
            }
            

Далее извлекаем из соответствующих полей нужную нам информацию.

Читаем версию.

wsprintf (szResourceX,
            "%01.1d,%01.1d,%01.1d,%01.1d",
            HIWORD (pFixedFileInfo->dwFileVersionMS),
            LOWORD(pFixedFileInfo->dwFileVersionMS),
            HIWORD (pFixedFileInfo->dwFileVersionLS),
            LOWORD(pFixedFileInfo->dwFileVersionLS));
            

Далее тип ОС, тип файла, подтип файла. Рассмотрим только получение подтипа файла, а остальное получается аналогично.

wsprintf(buff,
            " %d(%#x)",
            pFixedFileInfo->dwFileSubtype,
            pFixedFileInfo->dwFileSubtype);
            if(pFixedFileInfo->dwFileType == VFT_DRV)
            {
            switch(pFixedFileInfo->dwFileSubtype)
            {
            case VFT2_UNKNOWN :
            strcat(buff, " : VFT2_UNKNOWN"); break;
            case VFT2_DRV_PRINTER :
            strcat(buff, " : VFT2_DRV_PRINTER"); break;
            case VFT2_DRV_KEYBOARD :
            strcat(buff, " : VFT2_DRV_KEYBOARD"); break;
            case VFT2_DRV_LANGUAGE :
            strcat(buff, " : VFT2_DRV_LANGUAGE"); break;
            case VFT2_DRV_DISPLAY :
            strcat(buff, " : VFT2_DRV_DISPLAY"); break;
            case VFT2_DRV_MOUSE :
            strcat(buff, " : VFT2_DRV_MOUSE"); break;
            case VFT2_DRV_NETWORK :
            strcat(buff, " : VFT2_DRV_NETWORK"); break;
            case VFT2_DRV_INSTALLABLE :
            strcat(buff, " : VFT2_DRV_INSTALLABLE"); break;
            case VFT2_DRV_SOUND :
            strcat(buff, " : VFT2_DRV_SOUND"); break;
            case VFT2_DRV_COMM :
            strcat(buff, " : VFT2_DRV_COMM"); break;
            case VFT2_DRV_INPUTMETHOD :
            strcat(buff, " : VFT2_DRV_INPUTMETHOD"); break;
            }
            }
            else
            {
            if(pFixedFileInfo->dwFileType == VFT_FONT)
            {
            switch(pFixedFileInfo->dwFileSubtype)
            {
            case VFT2_FONT_RASTER :
            strcat(buff, " : VFT2_FONT_RASTER"); break;
            case VFT2_FONT_VECTOR :
            strcat(buff, " : VFT2_FONT_VECTOR"); break;
            case VFT2_FONT_TRUETYPE :
            strcat(buff, " : VFT2_FONT_TRUETYPE"); break;
            }
            }
            else strcat(buff, " : VFT2_UNKNOWN");
            }
            

 

 


Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.