|
|
Информация о версии файла
Опубликовано: 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;
lpFixedFileInf = new char[dwSizeFVerInf];
BOOL bRet = ::GetFileVersionInfo(
(LPTSTR)(LPCTSTR)DllName,
NULL,
dwSizeFVerInf,
lpFixedFileInf);
if(bRet == FALSE)
{
}
|
После этого получаем указатель на VS_FIXEDFILEINFO. Для этого передаём в функцию VerQueryValue вторым параметром значение “//”. Третьим параметром передаем указатель на структуру VS_FIXEDFILEINFO. В четвёртом параметре функция возвращает длину в символах данной структуры.
VS_FIXEDFILEINFO *pFixedFileInfo;
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");
}
|
Любой из материалов, опубликованных на этом сервере, не может быть воспроизведен в какой бы то ни было форме и какими бы то ни было средствами без письменного разрешения владельцев авторских прав.
|