Главная » Шпаргалка » DELPHI INTERBASE FireBird » Системная информация о компьютере

Системная информация о компьютере

1. Введение.

В статье рассматриваются способы получения системной информации о компьютере (операционная система, статус памяти, процессор и др.) Большинство примеров опирается на Windows API. Робота их подразумевается только под WIN32 (лишь отдельные функции работают под WIN32s). Статья направлена на аудиторию программистов Delphi, но может быть полезна программистам и других сред разработки приложений, интересующимся API и системной информацией. В статье использованы документы сайта http://apiwallst.ru/ , а также коды:

  • SysInfo Component, Angel's;
  • TSysInfo Component, RicoSoft;
  • TSYSINFO 2.1, Brent Boswell.

Главы о памяти и процессах ранее мной публиковались в интернете. Здесь они представлены с незначительными изменениями. Остальные главы публикуются впервые.

2. Состояние памяти.

Для получения детальной информации о состоянии памяти компьютера предназначена функция API GlobalMemoryStatus. В функцию передается переменная типа TMemoryStatus, которая представляет собой запись, тип которой определен следующим образом:

type
TMemoryStatus = record
dwLength: DWORD;
dwMemoryLoad: DWORD;
dwTotalPhys: DWORD;
dwAvailPhys: DWORD;
dwTotalPageFile: DWORD;
dwAvailPageFile: DWORD;
dwTotalVirtual: DWORD;
dwAvailVirtual: DWORD;
end;

Поля записи имеют следующий смысл:

dwLength Длина записи. Поле необходимо инициализировать функцией SizeOf до обращения к функции GlobalMemoryStatus.
dwMemoryLoad Количество использованной памяти в процентах.
dwTotalPhys Число байт установленной на компьютере ОЗУ (физической памяти).
dwAvailPhys Свободная физическая память в байтах.
dwTotalPageFile Общий объем в байтах, который могут сохранить файлы/файл подкачки (вообще говоря, не совпадает с размером последних).
dwAvailPageFile Доступный объем из последней величины в байтах.
dwTotalVirtual Общее число байтов виртуальной памяти, используемой в вызывающем процессе.
dwAvailVirtual Объем виртуальной памяти, доступной для вызывающего процесса.

Можно использовать следующий код получения информации о наличной памяти ОЗУ:

function GetRAM: Cardinal;
var MS: TMemoryStatus;
begin
MS.dwLength:=SizeOf(MS);
GlobalMemoryStatus(MS);
Result:=MS.dwTotalPhys;
end;

Пользовательская функция GetRAM возвращает общее число байт физической памяти, установленной на компьютере. Эту информацию она читает из поля dwTotalPhys записи MS, имеющей тип TMemoryStatus. Перед этим вызывается API-функция GlobalMemoryStatus с параметром MS. Обратите внимание, что перед вызовом GlobalMemoryStatus инициализируется поле dwLength функцией SizeOf.

По аналогии с примером можно получить информацию об остальных параметрах памяти, для этого надо заменить строку Result:=MS.dwTotalPhys на одну из перечисленных ниже:

Result:=MS.dwMemoryLoad;
Result:=MS.dwAvailPhys;
Result:=MS.dwTotalPageFile;
Result:=MS.dwAvailPageFile;
Result:=MS.dwTotalVirtual;
Result:=MS.dwAvailVirtual;

3. Информация о процессоре.

Функция GetSystemInfo с единственным параметром типа записи TSystemInfo дает доступ к различной системной информации. В частности, уровень процессора можно узнать из поля записи TSystemInfo – wProcessorLevel. Соответствие значений поля и основных уровней процессора приведено в таблице:

Значение поля wProcessorLevelУровень процессора
3 80386
4 80486
5 Pentium
6 Pentium Pro

Следующая пользовательская функция определяет уровень процессора:

function GetProcessorLevel: String;
var SI: TSystemInfo;
begin
GetSystemInfo(SI);
Case SI.wProcessorLevel of
3: Result:='80386';
4: Result:='80486';
5: Result:='Pentium';
6: Result:='Pentium Pro'
else Result:=IntToStr(SI.wProcessorLevel);end;
end;

Тактовую частоту процессора можно вычислить на основе следующего кода, использующего Ассемблер. Я его заимствовал, он хорошо работает, деталей реализации не знаю - привожу его без комментариев:

function GetCPUSpeed: Double;
const DelayTime = 500;
var TimerHi : DWORD;
TimerLo : DWORD;
PriorityClass : Integer;
Priority : Integer;
begin
PriorityClass := GetPriorityClass(GetCurrentProcess);
Priority := GetThreadPriority(GetCurrentThread);
SetPriorityClass(GetCurrentProcess, REALTIME_PRIORITY_CLASS);
SetThreadPriority(GetCurrentThread, THREAD_PRIORITY_TIME_CRITICAL);
Sleep(10);
asm
DW 310Fh // rdtsc
MOV TimerLo, EAX
MOV TimerHi, EDX
end;
Sleep(DelayTime);
asm
DW 310Fh // rdtsc
SUB EAX, TimerLo
SBB EDX, TimerHi
MOV TimerLo, EAX
MOV TimerHi, EDX
end;
SetThreadPriority(GetCurrentThread, Priority);
SetPriorityClass(GetCurrentProcess, PriorityClass);
Result := TimerLo / (1000.0 * DelayTime);
end;

Данная пользовательская функция возвращает тактовую частоту процессора.

4. Информация о дисках.

Функция GetDriveType возвращает значение, по которому можно определить тип диска. Аргумент функции – буква, связанная с диском. Возвращаемые функцией значения и их смысл приведены в таблице:

Возвращаемое значениеСмысл
0 Неизвестный
1 Не существует
Drive_Removable Съемный
Drive_Fixed Постоянный
Drive_Remote Внешний
Drive_CDROM Привод CD
Drive_RamDisk Диск RAM

Следующая пользовательская функция иллюстрирует использование функции GetDriveType. По букве диска она определяет тип диска и возвращает последний в строку:

function GetDrive(Drive: String): String;
var
DriveType : uInt;
begin
DriveType := GetDriveType(PChar(Drive));
case DriveType of
0: Result := '?';
1: Result := 'Path does not exists';
Drive_Removable: Result := 'Removable';
Drive_Fixed: Result := 'Fixed';
Drive_Remote: Result := 'Remote';
Drive_CDROM: Result := 'CD-ROM';
Drive_RamDisk: Result := 'RAMDisk'
else Result := 'Unknown';
end;
end;

Для определения размера диска служит функция DiskSize. Параметр, который в нее передается – номер диска (0 – текущий, далее по порядку: 1 – A, 2 – B и т.д.). Для получения размера в Мегабайтах можно использовать следующую пользовательскую функцию:

function GetDriveSize(Num: Byte): String;
begin
if DiskSize(Num) <> -1 then
Result := format('%d MB', [Trunc(DiskSize(Num)/1024/1024)])
else
Result := '';
end;

При ошибке ответ – пустая строка.

5. Операционная система.

Информация об операционной системе хранится в записи типа TOSVersionInfo, выглядещей следующим образом:

type
TOSVersionInfo = record
dwOSVersionInfoSize: DWORD;
dwMajorVersion: DWORD;
dwMinorVersion: DWORD;
dwBuildNumber: DWORD;
dwPlatformId: DWORD;
szCSDVersion: array [0..126] of AnsiChar;
end;

Поля записи имеют следующий смысл:

dwOSVersionInfoSize Размер записи.
dwMajorVersion Старший номер версии ОС.
dwMinorVersion Младший номер версии ОС.
dwBuildNumber Номер сборки ОС (в нижнем слове поля).
dwPlatformId Платформа.
szCSDVersion Строка поддержки для использования PSS. Содержит дополнительную информацию об ОС. Чаще всего – это пустая строка.

Поле dwPlatformId может иметь следующие значения:

Ver_Platform_Win32s Win32s в Windows 3.1
Ver_Platform_Windows Win32 в Windows 95
Ver_Platform_Win32_NT Windows NT

Получить информацию об ОС позволяет API-функция GetVersionEx с единственным параметром типа TOSVersionInfo. Приведу пример ее использования:

function GetOS(var MajVer:Byte; var MinVer:Byte; var BuildNo:Word):String;
var VI: TOSVersionInfo;
begin
VI.dwOSVersionInfoSize:=SizeOf(VI);
GetVersionEx(VI);
MajVer:= VI.dwMajorVersion;
MinVer:= VI.dwMinorVersion;
BuildNo:= LoWord(VI.dwBuildNumber);
Result:= 'OS Version '+
IntToStr(MajVer)+'.'+
IntToStr(MinVer)+' build No '+
IntToStr(BuildNo);
end;

Пользовательская функция GetOS выводит строку с номером версии ОС. Обратите внимание, что перед вызовом GetVersionEx инициализируется поле dwOSVersionInfoSize функцией SizeOf.

Другой вариант реализации пользовательской функции получения информации о версии ОС может быть, например, таким (здесь используется дополнительная информация о системе из поля szCSDVersion):

function GetOS_2: string;
var
OSVersion: TOSVersionInfo;
begin
OSVersion.dwOSVersionInfoSize := SizeOf(OSVersion);
if GetVersionEx(OSVersion) then
Result:= Format('%d.%d (%d.%s)',
[OSVersion.dwMajorVersion, OSVersion.dwMinorVersion,
(OSVersion.dwBuildNumber and $FFFF), OSVersion.szCSDVersion]);
end;

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

function GetPlatform: String;
var VI: TOSVersionInfo;
begin
VI.dwOSVersionInfoSize:=SizeOf(VI);
GetVersionEx(VI);
Case VI.dwPlatformId of
Ver_Platform_Win32s: Result:= 'Win32s';
Ver_Platform_Win32_Windows: Result:='Win95';
Ver_Platform_Win32_NT: Result:='WinNT'
else Result:='Unknown Platform'; end;
end;

6. Информация об основных каталогах.

Три функции дают пути к трем основным каталогам: GetWindowsDirectory – к каталогу ОС, GetSystemDirectory – к системной папке ОС и GetCurrentDirectory – к текущей папке. Эти функции имеют два параметра – путь к папке и размер его представления в памяти.

Следующая пользовательская функция иллюстрируют применение функции GetWindowsDirectory для получения пути к каталогу Windows:

function GetWindowsDir: string;
var S: array[0..MAX_PATH] of Char;
begin
GetWindowsDirectory(S,SizeOf(S));
Result:=S;
end;

Для получения пути к системной папке в вышеприведенном примере вместо строки GetWindowsDirectory(S,SizeOf(S)) надо использовать GetSystemDirectory(S,SizeOf(S)), а для получения пути к текущему каталогу - GetCurrentDirectory(SizeOf(S),S). Комментарии тут, думаю, излишни. Замечу только, что в обращении к функции GetCurrentDirectory первым параметром стоит размер пути, в отличие от двух других функций, где он на втором месте.

7. Информация о пользователе и компьютере.

Имя компьютера позволяет получить функция GetComputerName. В нее передается два параметра – параметр типа PChar, в который записывается имя компьютера и второй параметр, определяющий длину записи под имя. Следующая пользовательская функция выводит имя компьютера в строку:

function GetCompName: String;
var
i: DWORD;
p: PChar;
begin
i:=255;
GetMem(p, i);
GetComputerName(p, i);
Result:=String(p);
FreeMem(p);
end;

Очень похожим способом получается имя пользователя из функции GetUserName:

Pages:   1 | 2  Next