Download as pdf or txt
Download as pdf or txt
You are on page 1of 7

НАЦІОНАЛЬНИЙ УНІВЕРСИТЕТ БІОРЕСУРСІВ І

ПРИРОДОКОРИСТУВАННЯ УКРАЇНИ ФАКУЛЬТЕТ


ІНФОРМАЦІЙНИХ ТЕХНОЛОГІЙ

Лабораторна робота №6

Виконав:

Студент ІПЗ-21009б

Пащенко Максим

Київ-2023

Мета роботи: провести дослідження способу використання функцій Win32


API для отримання інформації про процеси, потоки, модулі та купи ОС
Windows у консольному додатку мовою C++.
Завдання

Провести системне дослідження способу використання функцій Win32 API


для отримання інформації про процеси, потоки, модулі та купи ОС Windows у
консольному додатку мовою C++.

1. Написати програму на мові С++ служби перевірки з'єднань в мережах


на основі протоколу TCP/IP.

2. За результатами вивчення теоретичних відомостей і практичних


досліджень скласти звіт та обґрунтувати висновки.

МЕТОДИКА ВИКОНАННЯ

2.1. Виконати базові завдання:

Вивести на екран перелік процесів, що виконуються в системі. Для вибраного


процесу (ввести його ідентифікатор) вивести відомості про його пріоритет та
кількість потоків. Для вибраного прикладного процесу (ввести його
ідентифікатор) вивести час його роботи в режимі ядра та в режимі
користувача.

2. 2.Вивести на екран інформацію про завантаження кожного ядра


процесора або завантаження процесора кожним процесом.

2.3. Вивести список імен виконуваних процесів із зазначенням Ю та


кількості потоків, упорядкувати список за кількістю потоків процесів.

2.4. Для вибраного прикладного процесу вивести розмір робочої


множини. Процес вибирається шляхом введення його PID.
#include <Windows.h>
#include <tlhelp32.h>
#include <clocale>
#include <Psapi.h>
#include <vector>
#include <algorithm>
#include <iostream>
#include <string>

using namespace std; struct


ProcessInfo {
wstring name; int
threadCount; DWORD
PID;
FILETIME userTime;
FILETIME kernelTime;
FILETIME creationTime;
};
bool CompareByThreadCount(const ProcessInfo& a, const ProcessInfo& b) {
return a.threadCount < b.threadCount;
} int main()
{
setlocale(LC_CTYPE, "");
cout << "\n\tСписок процесiв з кiлькiстю потокiв та навантаженням на
процесор\n";
cout << "--------------------------------------------------------------
------------\n";
cout << " № Процес Потоки СРU (User) мс CPU(Kernel)мс\n\n";
HANDLE snapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
PROCESSENTRY32 processEntry;
processEntry.dwSize = sizeof(PROCESSENTRY32);
vector<ProcessInfo> processList; if
(Process32First(snapshot, &processEntry)) {
do {
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, FALSE, processEntry.th32ProcessID);
if (hProcess) {
THREADENTRY32 threadEntry;
threadEntry.dwSize = sizeof(THREADENTRY32);
int threadCount = 0; HANDLE
snapshotThreads =
CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (Thread32First(snapshotThreads, &threadEntry)) {
do {
if (threadEntry.th32OwnerProcessID == processEntry.th32ProcessID) {
threadCount++;
}
} while (Thread32Next(snapshotThreads,
&threadEntry));
}
CloseHandle(snapshotThreads);
FILETIME creationTime, exitTime, kernelTime, userTime;
if (GetProcessTimes(hProcess, &creationTime, &exitTime,
&kernelTime, &userTime)) {
ProcessInfo processInfo;
processInfo.name = processEntry.szExeFile;
processInfo.PID = processEntry.th32ProcessID;
processInfo.threadCount = threadCount;
processInfo.creationTime = creationTime;
processInfo.userTime = userTime;
processInfo.kernelTime = kernelTime;
processList.push_back(processInfo);
}
CloseHandle(hProcess);
}
} while (Process32Next(snapshot, &processEntry));
CloseHandle(snapshot);
}
sort(processList.begin(), processList.end(), CompareByThreadCount); for
(const ProcessInfo& processInfo : processList) {
ULONGLONG userTimeMs = (processInfo.userTime.dwHighDateTime << 32 |
processInfo.userTime.dwLowDateTime) / 10000;
ULONGLONG kernelTimeMs = (processInfo.kernelTime.dwHighDateTime << 32
|processInfo.kernelTime.dwLowDateTime) / 10000;
wprintf(L"%-6d %-30s %d %-5lld %-5lld \n",processInfo.PID,
processInfo.name.c_str(), processInfo.threadCount,userTimeMs, kernelTimeMs);
}
cout << "\nВведiть iдентифiкатор процеса для отпримання iнформацiї: "; DWORD
processID;
cin >> processID;
HANDLE processHandle = OpenProcess(PROCESS_QUERY_INFORMATION |
PROCESS_VM_READ, FALSE, processID);
if (processHandle == NULL) {
cerr << "Помилка при вiдкриттi процеса." << endl;
return 1;
}
DWORD priority = GetPriorityClass(processHandle); cout <<
"Прiорiтет процеса: " << priority << endl;
HANDLE threadSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPTHREAD, 0);
if (threadSnapshot != INVALID_HANDLE_VALUE) { THREADENTRY32
threadEntry;
threadEntry.dwSize = sizeof(THREADENTRY32); DWORD
threadCount = 0;
if (Thread32First(threadSnapshot, &threadEntry)) {
do {
if (threadEntry.th32OwnerProcessID == processID) {
threadCount++;
}
} while (Thread32Next(threadSnapshot, &threadEntry));
}
cout << "Кiлькiсть потокiв: " << threadCount << endl;
CloseHandle(threadSnapshot);
}
else {
cerr << "Помилка при отриманнi iнформацiї о потоках." << endl;
}
FILETIME createTime, exitTime, kernelTime, userTime;
if (GetProcessTimes(processHandle, &createTime, &exitTime, &kernelTime,
&userTime)) {
ULARGE_INTEGER kernelTimeValue;
kernelTimeValue.LowPart = kernelTime.dwLowDateTime;
kernelTimeValue.HighPart = kernelTime.dwHighDateTime;
ULARGE_INTEGER userTimeValue;
userTimeValue.LowPart = userTime.dwLowDateTime;
userTimeValue.HighPart = userTime.dwHighDateTime;
cout << "Час роботи в режимi користувача: " << userTimeValue.QuadPart
/10000 << " мс" << endl;
cout << "Час роботи в режимi ядра: " << kernelTimeValue.QuadPart / 10000 << " мс"
<< endl;
}
else {
cerr << "Помилка при отриманнi iнформацiї про час роботы процесса."
<<endl;
}

HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ,


FALSE, processID);
if (hProcess) {
PROCESS_MEMORY_COUNTERS_EX pmc;
if (GetProcessMemoryInfo(hProcess, (PROCESS_MEMORY_COUNTERS*)&pmc, sizeof(pmc)))
{
SIZE_T workingSetSize = pmc.WorkingSetSize / (1024 * 1024);
cout << "Розмiр робочої множини процесса (МБ): " << workingSetSize<< " МБ" <<
std::endl;
}
else {
cerr << "Не вдалося отримати iнформацiю о пам'ятi процеса. Код
помилки: " << GetLastError() << std::endl;
}
CloseHandle(hProcess);
}
else {
cerr << "Не вдалося вiдкрити процес. Код помилки: " << GetLastError() <<
std::endl;
}
SYSTEM_INFO systemInfo;
GetSystemInfo(&systemInfo);
DWORD numProcessors = systemInfo.dwNumberOfProcessors;
FILETIME idleTime, kernelTimeTotal, userTimeTotal;
if (GetSystemTimes(&idleTime, &kernelTimeTotal, &userTimeTotal)) {
ULONGLONG kernelTimeValueTotal =
((ULONGLONG)kernelTimeTotal.dwHighDateTime << 32) | kernelTimeTotal.dwLowDateTime;
ULONGLONG userTimeValueTotal =
((ULONGLONG)userTimeTotal.dwHighDateTime<< 32) | userTimeTotal.dwLowDateTime;
cout << "Навантаження кожного ядра процесора:" << endl; for
(DWORD i = 0; i < numProcessors; i++) {
Sleep(300);
FILETIME idleTimeAfter, kernelTimeAfter, userTimeAfter;
if (GetSystemTimes(&idleTimeAfter, &kernelTimeAfter,
&userTimeAfter
)) {
ULONGLONG kernelTimeValueAfter =
((ULONGLONG)kernelTimeAfter.dwHighDateTime << 32) | kernelTimeAfter.dwLowDateTime;
ULONGLONG userTimeValueAfter =
((ULONGLONG)userTimeAfter.dwHighDateTime << 32) | userTimeAfter.dwLowDateTime;
LONGLONG kernelTimeDiff = kernelTimeValueAfter -
kernelTimeValueTotal;
LONGLONG userTimeDiff = userTimeValueAfter -
userTimeValueTotal;
LONGLONG totalTimeDiff = kernelTimeDiff + userTimeDiff; double
processorLoad = (1.0 -
(static_cast<double>(idleTimeAfter.dwLowDateTime -
idleTime.dwLowDateTime) /
static_cast<double>(totalTimeDiff))) * 100.0;
cout << "Ядро " << i << ": " << processorLoad << "%" <<
endl;
kernelTimeValueTotal = kernelTimeValueAfter; userTimeValueTotal
= userTimeValueAfter; idleTime = idleTimeAfter;
}
}
}
else {
cerr << "Помилка при отриманнi iнформацiї о навантаженнi процесора." <<
endl;
}
CloseHandle(processHandle);
system("pause");
return 0;
}
Висновок: під час виконання лабораторної роботи я провів дослідження
способу використання функцій Win32 API для отримання інформації про
процеси, потоки.

You might also like