ВВЕДЕНИЕ
Задача получения списка выполняющихся в системе процессов является одной из основных при выполнении мониторинга ресурсов как отдельного ПК, так и ЛВС в целом, поэтому для ее решения разработано значительное количество утилит, имеется встроенное системное средство – диспетчер задач.
Все перечисленные программные средства используют как функции Win32 API (Application Program Interface – прикладной программный интерфейс), так и функции еще одного базового интерфейса, называемого Native API (естественный API). Внешняя часть Native API пользовательского режима содержится в модуле ntdll.dll, «настоящий» интерфейс реализован в ntoskernel.exe – ядре операционной системы NT (NT operation system kernel). Функции Win32 API, как правило, обращаются к функциям Native API, отбрасывая часть полученной от них информации. Поэтому использование функций Native API позволяет получить, вообще говоря, более эффективное ПО.
К функциям Win32 API для получения информации о выполняющихся в системе процессах относятся функции CreateToolHelp32Snapshot(), Process32First(), Process32Next(), Thread32First(), Thread32Next(), Module32First(), Module32Next(), Heap32ListFirst(), Heap32ListNext() и некоторые другие. Самая известная из функций Native API для доступа к содержимому многих важных внутренних структур операционной системы, таких как списки процессов, потоков, дескрипторов, драйверов и т.п., – функция ntQuerySystemInformation () – вывод счетчика производительности.
Студенты заочной формы обучения выполняют контрольную работу. Для этого каждый студент получает у ведущего преподавателя карточку-задание, изображенную на рисунке 1.
Вариант №__
Вывести на форму список процессов с указанием приоритета. Список должен обновляться при нажатии на кнопку «Обновить».
Для каждого прикладного процесса вывести время его старта и время работы в режиме пользователя.
Предусмотреть возможность завершения выбранного из списка прикладного процесса по кнопке «Завершить».
На форму выводить следующие статистические сведения:
· общее количество процессов;
· общее количество потоков;
· имя процесса, запущенного последним.
|
Рис. 1. Карточка-задание на контрольную работу для студента
БАЗОВЫЕ ФУНКЦИИ
Цель работы – практическое знакомство с методикой использования базовых функций для получения информации о процессах, потоках, модулях и кучах ОС Windows XP.
Краткие теоретические сведения
Получение списка процессов, выполняющихся в системе
1.1.1 Использование функций CreateToolHelp32Snapshot () и Process32xxxx()
для получения списка имен процессов
Первый этап получения информации о выполняющихся в системе процессах –получение снимка (snapshot) системы, который содержит информацию о состоянии системы в момент выполнения снимка.
Снимок создается с помощью функции CreateToolHelp32Snapshot (dwFlags, th32ProcessID), первый аргумент определяет, какая информация будет записана в снимок. Возможные значения dwFlags приведены в таблице 1.
Таблица 1
Возможные значения dwFlags
Флаг - dwFlags | Описание |
TH32CS_SnapHEAPLIST | В снимок включается список куч, принадлежащих указанному процессу |
TH32CS_SnapPROCESS | В снимок включается список процессов, присутствующих в системе |
TH32CS_SnapTHREAD | В снимок включается список потоков |
TH32CS_SnapMODULE | В снимок включается список модулей, принадлежащих указанному процессу |
TH32CS_SnapALL | В снимок включается список куч, процессов, потоков и модулей |
Второй аргумент определяет процесс, информация о котором необходима (если требуется список куч и модулей). В остальных случаях он игнорируется.
Второй этап – извлечение из снимка списка процессов. Для выполнения этой операции служат функции:
Process32First (hSnapshot, LPProcessEntry32);
Process32Next (hSnapshot, LPProcessEntry32).
Первый аргумент – хэндл созданного снимка (возвращает функция CreateToolHelp32Snapshot).
Второй аргумент – структура, содержащая 10 полей:
1. Первое поле – dwSize – размер структуры в байтах. Это единственное поле, которое должно быть заполнено до вызова функции Process32First. Заполнить его можно, используя выражение sizeof(PROCESSENTRY32).
2. Второе поле – cntUsage – содержит число ссылок на процесс, то есть число потоков, которые в настоящий момент используют какие-либо данные процесса.
3. Третье поле – th32ProcessID – является идентификатором процесса.
4. Четвертое поле – th32DefaultHeapID – не используется, и всегда устанавливается в ноль.
5. Пятое поле – th32ModuleID – не используется, и всегда устанавливается в ноль.
6. Шестое поле – cntThreads – определяет число потоков, принадлежащих процессу.
7. Седьмое поле – th32ParentProcessID – является идентификатором родительского по отношению к текущему процесса.
8. Восьмое поле – pcPriClassBase – содержит базовый приоритет процесса.
9. Девятое поле – dwFlags – не используется, и всегда устанавливается в ноль.
10. Десятое поле – szExeFile – содержит имя файла, создавшего процесс.
Для того, чтобы получить информацию о первом процессе в снимке, необходимо вызвать функцию Process32First. В случае успешного завершения функция возвращает TRUE. Для того, чтобы просмотреть все оставшиеся процессы, нужно вызывать функцию Process32Next до тех пор, пока она не возвратит FALSE.
В список используемых модулей – uses – необходимо добавить модуль TlHelp32
Пример 1. Получить список имен выполняющихся в системе процессов, используя рассмотренные выше функции.
На форме размещены компоненты ListBox, Label и Button, обработчик события OnClick имеет вид:
var
SH: Thandle;
Num,I: Integer;
PPE: TProcessEntry32;
Pr_names: array [0..80] of string;
begin
Num:= 0;
// получение снимка состояния системы
SH:= CreateToolHelp32SnapShot(Th32cs_SnapAll,0);
// выделение из снимка имени первого процесса
PPE.dwSize:= sizeof(ProcessEntry32);
Process32First(SH,PPE);
Pr_Names[Num]:= PPE.szExeFile;
// получение имен других процесса
while Process32Next(SH,PPE) do
begin
Num:= Num+1;
Pr_Names[Num]:= PPE.szExeFile;
end;
Listbox1.Clear;
// вывод списка имен выполняющихся процессов
for I:=0 to Num do Listbox1.Items.Add(Pr_Names[I]);
// освобождение ресурса – снимка состояния системы
CloseHandle(SH)
end;
Результат выполнения примера 1 показан на рис. 2.
Рис. 2. Список выполняющихся процессов
1.1.2 Использование функций CreateToolHelp32Snapshot () и Thread32xxxx()
для получения сведений о приоритетах потоков процессов
Для получения сведений о приоритетах потоков необходимо извлечь из снимка состояния системы с помощью функций Thread32First() и Thtead32Next () значения соответствующих полей.
Обращение к функциям имеет вид:
Thread32First (hSnapshot, LPTHREADEntry32)
Thtead32Next (hSnapshot, LPTHREADEntry32).
Первый аргумент – хэндл созданного снимка (возвращает функция CreateToolHelp32Snapshot).
Второй аргумент – структура, содержащая 7 полей:
1. Первое поле – dwSize – размер структуры в байтах. Это единственное поле, которое должно быть заполнено до вызова функцииThread32First. Заполнить его можно, используя выражение sizeof( Thread Entry32).
2. Поле – cntUsageth –не используется и всегда устанавливается в ноль.
3. Поле – 32ThreadID – не используется и всегда устанавливается в ноль.
4. Поле – th32OwnerProcessID – содержит идентификатор родительского процесса.
5. Поле – tpBasePri – содержит текущий приоритет потока.
6. Поле – tpDeltaPri – содержит разность между текущим уровнем приоритета потока и базовым уровнем, то есть тем, который присваивается при создании потока.
7. Поле – dwFlags – не используется и всегда устанавливается в ноль.
Пример 2. Получить список выполняющихся в системе потоков, используя рассмотренные выше функции. Вывести содержимое полей 2 и 3 структуры THREADEntry32.
На форме размещены компоненты ListView, Label и Button, обработчик события OnClick имеет вид:
var
Sh: Thandle;
Th: TTHREADENTRY32;
LstIt: TlistItem;
begin
Sh:= CreateToolHelp32Snapshot(TH32CS_SNAPALL,0);
Th.dwSize:= sizeof(TTHREADEntry32);
Thread32First(sh,Th);
ListView1.Items.Clear;
LstIt:=ListView1.Items.Add;
LstIt.Caption:=IntToStr(Th.th32OwnerProcessID);
LstIt.SubItems.Add(IntToStr(Th.tpBasePri));
repeat
LstIt:=ListView1.Items.Add;
LstIt.Caption:=IntToStr(Th.th32OwnerProcessID);
LstIt.SubItems.Add(IntToStr(Th.tpBasePri))
until not Thread32Next(sh,Th);
CloseHandle(Sh);
end;
Созданы 2 Columns, имеющие заголовки «Идент процесса» и «Базовый приор потока» (свойства ListView).
ВАЖНО! Свойство ViewStyle компонента ListView должно быть установлено
в vsReport.
Результат выполнения примера 2 показан на рис. 3.
Рис. 3. Список потоков
1.1.3 Использование функций CreateToolHelp32Snapshot () и Module32xxxx()
для получения списка модулей
Для получения сведений о приоритетах потоков необходимо извлечь из снимка состояния системы с помощью функций Module32First() и Module32Next() значения соответствующих полей.
Обращение к функциям имеет вид:
Module32First (hSnapshot, LPMODULEENTRY32);
Module32Next (hSnapshot, LPMODULEENTRY32).
Первый аргумент – хэндл созданного снимка (возвращает функция CreateToolHelp32Snapshot).
Второй аргумент – структура, содержащая 10 полей:
1. Первое поле – dwSize – размер структуры в байтах. Это единственное поле, которое должно быть заполнено до вызова функцииModule 32First. Заполнить его можно, используя выражение sizeof( Module Entry32);
2. th32ModuleID: DWORD – размер модуля;
3. th32ProcessID: DWORD – идентификатор процесса, владеющего модулем;
4. GlblcntUsage: DWORD – счетчик глобальных пользователей модуля;
5. ProccntUsage: DWORD – счетчик процессов - пользователей;
6. modBaseAddr: BYTE – базовый адрес модуля;
7. modBaseSize: DWORD – базовый размер модуля;
8. hModule: HMODULE – хэндл модуля;
9. szModule: array [1.. MAX_MODULE_NAME32 + 1] of char – имя модуля;
10. szExePath: array [1.. MAX_PATH] of char – путь размещения модуля.
1.1.4 Использование функций CreateToolHelp32Snapshot () и Heap32Listxxxx()
для получения списка куч
Для получения сведений о кучах необходимо извлечь из снимка состояния системы с помощью функций Heap32ListFirst() и Heap32ListNext () значения соответствующих полей.
Обращение к функциям имеет вид:
Heap32ListFirst (hSnapshot, LPHEAPLIST32);
Heap32ListNext (hSnapshot, LPHEAPLIST32).
Первый аргумент – хэндл созданного снимка (возвращает функция CreateToolHelp32Snapshot).
Второй аргумент – структура, содержащая 4 поля:
1. dwSize: DWORD – размер кучи;
2. th32ProcessID: DWORD – идентификатор процесса, владеющего кучей;
3. th32HeapID: DWORD – идентификатор кучи;
4. dwFlags: DWORD – тип кучи.