Напомним лишь, чтобы вы не забывали заполнять поле dwOSVersionInf oSize перед вызовом функции GetVersionEx.
Итак, пример обработки данных, помещаемых в структуру OSVERSIONINFO, приведен в листинге 7.1. При загрузке формы элемент управления ListView с именем lvwVerlnf о заполняется сведениями о версии системы, представленными в читабельной форме.
Листинг 7.1.
Получение и отображение сведений о Windows
procedure TForm1.FormCreate (Sender: TObject);
var
info: OSVERSIONINFO;
item: TListItem;
begin
//Получаем информацию о версии ОС
info.dwOSVersionInfoSize := SizeOf(info);
GetVersionEx(info);
//Заполняем список информацией о ОС
//..версия ОС
item := lvwVerInfo.Items.Add();
item.Caption := 'Версия системы
item.SubItems.Insert(0, IntToStr(Integer(info.dwMajorVersion)) +
'.' + IntToStr(Integer (info.dwMinorVersion)));
//..номер сборки
item := lvwVerInfo.Items.Add ();
item.Caption := 'Сборка
item.SubItems.Insert(0, IntToStr(Integer (info.dwBuildNumber)));
//..платформа
item := lvwVerInfo.Items.Add();
item.Caption := 'Платформа
case info.dwPlatformId of
VER_PLATFORM_WIN32s:
//Эмуляция Win32 или Win16
item.SubItems.Insert(0, 'Win16');
VER_PLATFORM_WIN32_WINDOWS:
//'Классическая' Win32: 95, 98 или Me
item.SubItems.Insert(0, 'Win32');
VER_PLATFORM_WIN32_NT:
//Ядро NT
item.SubItems.Insert(0, 'WinNT');
end;
//..дополнительная информация (например, пакет обновлений)
item := lvwVerInfo.Items.Add();
item.Caption := 'Дополнительные сведения
item.SubItems.Insert(0, info.szCSDVersion);
end;
Возможный результат работы программы (для Windows ХР SP1) приводится на рис. 7.1.
Рис. 7.1. Информация о версии Windows
Теперь снова обратимся к функции GetVersionEx, точнее говоря, к структуре OSVERSIONINFOEX, которая может также передаваться в качестве параметра в функцию. К сожалению, в библиотеке Delphi 7 эта структура не объявлена. Но это можно сделать самостоятельно:
OSVERSIONINFO EX = record
dwOSVersionInfoSize: DWORD;
dwMajorVersion: DWORD;
dwMinorVersion: DWORD;
dwBuildNumber: DWORD;
dwPlatformId: DWORD;
szCSDVersion: array[0..127] of AnsiChar;
//Поля, которых нет в OSVERSIONINFO
wServicePackMajor: WORD; //Старшая цифра версии пакета
//обновлений
wServicePackMinor: WORD; //Младшая цифра версии пакета
//обновлений
wSuiteMask: WORD; //Комплектация системы
wProductType: BYTE; //Дополнительная информации об ОС
wReserved: BYTE;
end;
Дополнительные (по сравнению с OS VERS ION INFO) поля структуры может заполнить ОС Windows NT 4.0 SP6 и более поздние версии Windows NT (в том числе 2000 и ХР). Значения дополнительных полей структуры OSVERSIONINFOEX пояснены комментариями в объявлении структуры.
Значение поля wSuiteMask (является битовой маской) может быть составлено из значений следующих констант (увы, но их объявления также пришлось добавить самостоятельно).
VER_SUITE_BAC KOFFICE = 4; //Установлена Microsoft Back Office
VER_SUITE_DATACENTER = 128;//Установлена Microsoft Data Center
VER_SUITE_ENTERPRISE = 2; //Установлена ОС Windows 2000
//Advanced Server
VER_SUITE_SMALLBUSINESS = 1; //Установлена Microsoft Small
//Business Server
VER_SUITE_SMALLBUSINESS_RESTRICTED = 32; //Установлена
//ограниченная версия Microsoft
//Small Business Server
VER_SUITE_TERMINAL = 16; //Установлены терминальные службы
VER_SUITE_PERSONAL = 512; //Персональная версия ОС (типичный
//набор функций меньше, чем в Professional)
Значение поля wProductType может быть одним из приведенных ниже (тип сетевой ОС и соответственно роль, которую компьютер с данной ОС может исполнять при подключении в сети):
VER_NT_WORKSTATION = 1; //Рабочая станция
VER_NT_DOMAIN_CONTROLLER = 2; //Контроллер домена
VER_NT_SERVER = 3; //Сервер
Чтобы можно было просто передавать в функцию GetVersionEx ссылку на структуру OSVERSIONINFOEX, а не OSVERSIONINFO, перегрузим эту функцию следующим образом:
function GetVersionEx(var lpVersionInformation: OSVERSIONINFOEX): BOOL;
stdcall; external kernel32 name 'GetVersionExA
Теперь определение полной информации о версии ОС для случая Windows на платформе NT (выше NT 4.0 SP6) может выглядеть следующим образом (листинг 7.2) (часть, одинаковая с листингом 7.1, опущена).
Листинг 7.2.
Определение версии ОС (NT, 2000, ХР)
procedure TForm1.FormCreate(Sender: TObject);
var
info: OSVERSIONINFOEX;
item: TListItem;
suite, additional: String;
begin
//Получаем информацию о версии ОС
info.dwOSVersionInfoSize := SizeOf(info);
GetVersionEx(info);
//Заполняем список информацией об ОС
//…
//..версия о пакете обновлений
item := lvwVerInfo.Items.Add();
item.Caption := 'Версия ServicePack
item.SubItems.Insert
(0, IntToStr(Integer(info.wServicePackMajor)) + '.' +
IntToStr(Integer(info.wServicePackMinor)));
//..комплекация ОС
suite := '
if info.wSuiteMask and VER_SUITE_BACKOFFICE <> 0 then
suite := suite + '[Установлен Back Office]
if info.wSuiteMask and VER_SUITE_DATACENTER <> 0 then
suite := suite + '[Microsoft Data Center]
if info.wSuiteMask and VER_SUITE_ENTERPRISE <> 0 then
suite := suite + '[Windows 2000 Advanced Server]
if info.wSuiteMask and VER_SUITE_SMALLBUSINESS <> 0 then
suite := suite + '[Small Business Server]
if info.wSuiteMask and VER_SUITE_SMALLBUSINESS_RESTRICTED <> 0
then
suite := suite + '[Small Business Server, ограниченная версия]
if info.wSuiteMask and VER_SUITE_TERMINAL <> 0 then
suite := suite + '[Terminal Service]
if info.wSuiteMask and VER_SUITE_PERSONAL <> 0 then
suite := suite + '[Workstation Personal (не Professional)]
item := lvwVerInfo.Items.Add();
item.Caption := 'Комплектация
item.SubItems.Add(suite);
//..дополнительные сведения
additional := '
if info.wProductType and VER_NT_WORKSTATION <> 0 then
additional := additional + '[Рабочая станция]
if info.wProductType and VER_NT_DOMAIN_CONTROLLER <> 0 then
additional := additional + '[Контроллер домена]
if info.wProductType and VER_NT_SERVER <> 0 then
additional := additional + '[Сервер]
item := lvwVerInfo.Items.Add ();
item.Caption := 'Дополнительно
item.SubItems.Add (additional);
end;
Имя компьютера
Следующий простой пример (листинг 7.3) показывает, как можно определить сетевое имя компьютера. Функция ComputerName скрывает «прелести» работы со строковым буфером, который нужно передавать в API-функцию GetComputerName.
Листи нг 7.3.
Определение сетевого имени компьютера
function ComputerName(): String;
var
buffer: String;
len: Cardinal;
begin
len := MAX_COMPUTERNAME_LENGTH + 1;
SetLength(buffer, len);
if GetComputerName(PAnsiChar (buffer), len) <> False then
ComputerName := Copy(buffer, 1, len)
else
ComputerName := '
end;
Имя пользователя
Определить имя пользователя, от имени которого запущена программа (а точнее – вызывающий функцию поток), можно с использованием функции из листинга 7.4.
Листинг 7.4.
Определение имени пользователя
function UserName():