Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms
Практическая часть
1. Реализуйте описанные в лабораторной работе действия с процессами, потоками и окнами:
- для каждого процесса рядом с его именем файла, создавшего процесс, выведите зачение его идентификатора, приоритета и дескриптора (дескриптор процесса можно получить с помощью функции OpenProcess);
- для каждого потока, помимо идентификатора родительского процесса и базового приоритета, выведите идентификатор потока;
- для каждого окна, выведите информацию о его дочерних окнах (дескриптор, заголовок окна, прямоугольник вывода, идентификатор родительского процесса и потока);
- добавьте в компонент StringGrid1, используемый для вывода информации о дочерних окнах, подписи к столбцам.
2. Для выбранного из списка процесса выведите сведения о его потоках, используя компонент StringGrid.
3. Для выбранного из списка процесса постройте список всех созданных им окон с указанием состояния каждого окна (видимое-невидимое), используя компонент StringGrid и функцию IsWindowVisible, которая в качестве параметра принимает дескриптор окна.
4. Добавьте возможность завершения процессов системы (и с ручным вводом идентификатора, и с указанием процесса курсором в окне просмотра ListBox). Не завершайте все подряд, чтобы не перезагружать компьютер.
5. Добавьте возможность изменения приоритета выбранного процесса. Уровень приоритета должен выбираться из списка возможных значений.
Приоритет процесса устанавливается функцией SetPriorityClass, в качестве первого параметра предеается дескриптор процесса. Рекомендуется проверять возвращаемое функцией значение, чтобы убедиться, что желаемое действие выполнено успешно. Функция завершается успешно, если величина возвращаемого значения – не ноль; функция завершается с ошибкой, если величина возвращаемого значения – ноль. Для задания значений приоритета процесса следует использовать символические константы, передавая в функцию SetPriorityClass в качестве второго параметра:
REALTIME_PRIORITY_CLASS,
HIGH_PRIORITY_CLASS,
NORMAL_PRIORITY_CLASS,
IDLE_PRIORITY_CLASS.
6. Добавьте возможность делать доступным или не доступным выбранное окно из списка. Для этого необходимо использовать функцию EnableWindow(hWnd: HWND, bEnable:boolean):Boolean, первый параметр которой hWnd – дескриптор того окна, которое должно быть сделано доступным или недоступным, второй параметр bEnable – задает устанавливаемое значение доступности: true – доступно, false – недоступно.
7. Получите и выведите на экран сведения о модулях, используемых выбранным процессом.
8. Представьте, на основании полученных результатов, дерево процессов.
Листинг 1:
unit Unit1;
Interface
Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, TLHelp32, StdCtrls;
Type
TForm1 = class(TForm)
SGProcess: TStringGrid;
SGThread: TStringGrid;
LProcess: TLabel;
LThread: TLabel;
SGWindow: TStringGrid;
LChildWindow: TLabel;
LWindow: TLabel;
SGChildWindow: TStringGrid;
BStartThread: TButton;
BStartWindow: TButton;
EExitProcess: TEdit;
BExitProcess: TButton;
LExitProcess: TLabel;
RBRealtime: TRadioButton;
LPriorityProcess: TLabel;
RBHigh: TRadioButton;
RBNormal: TRadioButton;
RBIdle: TRadioButton;
BPriorityProcess: TButton;
RBWindowBlock: TRadioButton;
RBNoWindowBlock: TRadioButton;
BWindowBlock: TButton;
LWindowBlock: TLabel;
MModule: TMemo;
LModule: TLabel;
procedure FormCreate(Sender: TObject);
procedure SGWindowMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SGProcessMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BStartThreadClick(Sender: TObject);
procedure BStartWindowClick(Sender: TObject);
procedure BExitProcessClick(Sender: TObject);
procedure BPriorityProcessClick(Sender: TObject);
procedure BWindowBlockClick(Sender: TObject);
Private
{ Private declarations }
Public
{ Public declarations }
end;
Const
Max_Char=256;
Var
Form1: TForm1;
ColProcess, RowProcess : Integer;
ColWindow, RowWindow : Integer;
startThread : array [1..3, 1..2000] of string;
sizeStartThread : Integer;
startWindow : array [1..9, 1..1000] of string;
sizeStartWindow : Integer;
Implementation
{$R *.dfm}
procedure TForm1.BExitProcessClick(Sender: TObject);
Var
procId,Ex : Cardinal;
Handlep : Thandle;
Begin
if EExitProcess.Text = '' then
Procid:=StrToInt64(SGProcess.Cells[2, RowProcess]) { Окно служит для ручного ввода идентификатора завершаемого процесса }
Else
Procid:=StrToInt64(EExitProcess.Text); { Окно служит для ручного ввода идентификатора завершаемого процесса }
HANDLEp:= OpenProcess( PROCESS_TERMINATE, false, procid );
Var
handlep : Thandle;
Begin
handlep := OpenProcess(PROCESS_ALL_ACCESS, false, StrToInt(SGProcess.Cells[2, RowProcess]));
if RBRealtime.Checked then SetPriorityClass(handlep, REALTIME_PRIORITY_CLASS);
if RBHigh.Checked then SetPriorityClass(handlep, HIGH_PRIORITY_CLASS);
if RBNormal.Checked then SetPriorityClass(handlep, NORMAL_PRIORITY_CLASS);
if RBIdle.Checked then SetPriorityClass(handlep, IDLE_PRIORITY_CLASS);
FormCreate(Form1);
end;
procedure TForm1.BStartThreadClick(Sender: TObject);
Var
i, j: Integer;
Begin
SGThread.RowCount := sizeStartThread + 1;
for i := 1 to sizeStartThread do
Begin
for j := 1 to 3 do
SGThread.Cells[j, i] := startThread[j, i];
SGThread.Cells[0, i] := IntToStr(i);
end;
end;
procedure TForm1.BStartWindowClick(Sender: TObject);
Var
i, j: Integer;
Begin
SGWindow.RowCount := sizeStartWindow + 1;
for i := 1 to sizeStartWindow do
Begin
for j := 1 to 9 do
SGWindow.Cells[j, i] := startWindow[j, i];
SGWindow.Cells[0, i] := IntToStr(i);
end;
end;
procedure TForm1.BWindowBlockClick(Sender: TObject);
Var
handlep : Thandle;
Begin
if RowWindow > 0 then
Begin
handlep := StrToInt(SGWindow.Cells[1, RowWindow]);
if RBWindowBlock.Checked then EnableWindow(handlep, false);
if RBNoWindowBlock.Checked then EnableWindow(handlep, true);
end;
end;
procedure TForm1.FormCreate(Sender: TObject);
Var
Num, i, j: Integer;
SH: Cardinal;
PPE : TProcessEntry32;
Full_Path, Exe_name: array [0..255]of string;
ProcessID : array [0..255] of integer;
ProcessParentID : array [0..255] of integer;
ProcessPri : array [0..255] of integer;
PTE : TThreadEntry32;
ThreadProcessID : array [0..2000] of integer;
ThreadID : array [0..2000] of integer;
ThreadPri : array [0..2000] of integer;
DT_hWnd, next_hWnd, buflen : longint;
buf:array [0..Max_Char] of Char;
count : word;
Rect : TRect;
prId,thid : dword;
Begin
// получение информации о первоп процессе
Num := 0;
SH := CreateToolHelp32SnapShot(Th32cs_SnapAll, 0);
PPE.dwSize := sizeof(ProcessEntry32);
Process32First(SH, PPE);
Full_Path[Num] := PPE.szExeFile;
Exe_Name[Num] := ExtractFileName(Full_Path[Num]);
ProcessParentID[Num] := PPE.th32ParentProcessID;
ProcessID[Num] := PPE.Th32ProcessID;
Num := Num + 1;
// получение информации о других процессах
Begin
Full_Path[Num] := PPE.szExeFile;
Exe_Name[Num] := ExtractFileName(Full_Path[Num]);
ProcessID[Num]:= PPE.Th32ProcessID;
ProcessPri[Num] := PPE.pcPriClassBase;
ProcessParentID[Num] := PPE.th32ParentProcessID;
Num := Num + 1;
end;
//вывод полученной информации о процессах в таблицу на форме
LProcess.Caption := 'Список процессов';
SGProcess.Cells[0, 0] := '№';
SGProcess.Cells[1, 0] := 'Имя процесса';
SGProcess.Cells[2, 0] := 'Идентификатор';
SGProcess.Cells[3, 0] := 'Приоритет';
SGProcess.Cells[4, 0] := 'Дескриптор';
SGProcess.Cells[5, 0] := 'Родит. процесс';
SGProcess.RowCount := Num + 1;
i := 1;
while i <= Num + 1 do
Begin
SGProcess.Cells[0, i] := IntToStr(i);
SGProcess.Cells[1, i] := Exe_Name[i - 1];
SGProcess.Cells[2, i] := IntToStr(ProcessID[i - 1]);
SGProcess.Cells[3, i] := IntToStr(ProcessPri[i - 1]);
SGProcess.Cells[4, i] := IntToStr(OpenProcess(PROCESS_ALL_ACCESS, false, ProcessID[i - 1]));
SGProcess.Cells[5, i] := IntToStr(ProcessParentID[i - 1]);
i := i + 1;
end;
// получение информации о первом потоке
Num := 0;
PTE.dwSize := sizeof(TThreadEntry32);
Thread32First(SH, PTE);
ThreadProcessID[Num] := PTE.th32OwnerProcessID;
ThreadID[Num] := PTE.th32ThreadID;
ThreadPri[Num] := PTE.tpBasePri;
Num := Num + 1;
// получение информации о других потоках
Begin
ThreadProcessID[Num] := PTE.th32OwnerProcessID;
ThreadID[Num] := PTE.th32ThreadID;
ThreadPri[Num] := PTE.tpBasePri;
Num := Num + 1;
end;
//вывод полученной информации о потоках в таблицу на форме
LThread.Caption := 'Список потоков (для получения полного списка нпжмите Ok):';
SGThread.Cells[0, 0] := '№';
SGThread.Cells[1, 0] := 'Родит. процесс';
SGThread.Cells[2, 0] := 'Идентификатор';
SGThread.Cells[3, 0] := 'Приоритет';
SGThread.RowCount := Num + 1;
i := 1;
while i <= Num + 1 do
Begin
SGThread.Cells[0, i] := IntToStr(i);
SGThread.Cells[1, i] := IntToStr(ThreadProcessID[i - 1]);
SGThread.Cells[2, i] := IntToStr(ThreadID[i - 1]);
SGThread.Cells[3, i] := IntToStr(ThreadPri[i - 1]);
//сохраним эту таблицу в массив
for j := 1 to 3 do
startThread[j, i] := SGThread.Cells[j, i];
sizeStartThread := SGThread.RowCount - 1;
i := i + 1;
end;
//Список окон
LWindow.Caption := 'Список окон (для получения полного списка нпжмите Ok):';
DT_hWnd := GetDesktopWindow; // получить дескриптор окна рабочего стола
next_hWnd := GetWindow(DT_hWnd, GW_CHILD);
count := 0;
SGWindow.RowCount := 2;
SGWindow.Cells[0, 0] := '№';
SGWindow.Cells[1, 0] := 'Дескриптор';
SGWindow.Cells[2, 0] := 'Заголовок';
SGWindow.Cells[3, 0] := 'Лево';
SGWindow.Cells[4, 0] := 'Верх';
SGWindow.Cells[5, 0] := 'Право';
SGWindow.Cells[6, 0] := 'Низ';
SGWindow.Cells[7, 0] := 'Род. процесс';
SGWindow.Cells[8, 0] := 'Род. поток';
SGWindow.Cells[9, 0] := 'Видимость';
while next_HWnd <> 0 do
Begin
buflen := GetWindowText(next_HWnd, @buf, MaX_CHAR);
if buflen > 0 then
Begin
SGWindow.Cells[0, count + 1] := IntToStr(count + 1);
SGWindow.Cells[1, count + 1] := Format('%10d', [next_hWnd]);
SGWindow.Cells[2, count + 1] := Format('%s', [String(buf)]);
GetWindowRect(next_Hwnd,Rect);
thId := GetWindowThreadProcessId(next_Hwnd,@Prid);
SGWindow.Cells[3, count + 1] := IntToStr(Rect.Left);
SGWindow.Cells[4, count + 1] := IntToStr(Rect.Top);
SGWindow.Cells[5, count + 1] := IntToStr(Rect.Right);
SGWindow.Cells[6, count + 1] := IntToStr(Rect.Bottom);
SGWindow.Cells[7, count + 1] := IntToStr(Prid);
SGWindow.Cells[8, count + 1] := IntToStr(thid);
if IsWindowVisible(next_hWnd) then
SGWindow.Cells[9, count + 1] := 'true'
Else
SGWindow.Cells[9, count + 1] := 'false';
for j := 1 to 9 do
startWindow[j, count + 1] := SGWindow.Cells[j, count + 1];
sizeStartWindow := SGWindow.RowCount;
inc(count);
SGWindow.RowCount := count + 1;
end;
next_hWnd := GetWindow (next_hWnd, GW_HWNDNEXT);
end;
//дочерние окна
LChildWindow.Caption := 'Список дочерних окон';
SGChildWindow.Cells[0, 0] := '№';
SGChildWindow.Cells[1, 0] := 'Дескриптор';
SGChildWindow.Cells[2, 0] := 'Заголовок';
SGChildWindow.Cells[3, 0] := 'Лево';
SGChildWindow.Cells[4, 0] := 'Верх';
SGChildWindow.Cells[5, 0] := 'Право';
SGChildWindow.Cells[6, 0] := 'Низ';
SGChildWindow.Cells[7, 0] := 'Род. процесс';
SGChildWindow.Cells[8, 0] := 'Род. поток';
SGChildWindow.Cells[9, 0] := 'Видимость';
//потоки, принадлежащие некому процессу
SGThread.Cells[0, 0] := '№';
SGThread.Cells[1, 0] := 'Родит. процесс';
SGThread.Cells[2, 0] := 'Идентификатор';
SGThread.Cells[3, 0] := 'Приоритет';
//Уничтожение процесса
LExitProcess.Caption := 'Введите ID или оставьте поле пустым и выберите процесс из списка:';
EExitProcess.Text := '';
//Изменение приоритета процесса
LPriorityProcess.Caption := 'Изменение приоритета процесса:';
RBRealtime.Caption := 'Наивысший';
RBHigh.Caption := 'Высокий';
RBNormal.Caption := 'Нормальный';
RBIdle.Caption := 'Низкий';
//Блокировка окон
LWindowBlock.Caption := 'Блокировка окон:';
RBWindowBlock.Caption := 'Блокировать';
RBNoWindowBlock.Caption := 'Разблокировать';
//Модули процесса
LModule.Caption := 'Модули процесса';
Mmodule.Lines.Clear;
CloseHandle(SH);
end;
procedure TForm1.SGProcessMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Var
count, n, i : Integer;
SH: Cardinal;
PME : TModuleEntry32;
Begin
{вывод потоков}
SGProcess.MouseToCell(X, Y, ColProcess, RowProcess);
//очистка рабочей области таблицы
for count := 1 to SGThread.RowCount - 1 do
SGThread.Rows[count].Clear;
SGThread.RowCount := 2;
//если не строка с заголовками столбцов, то:
if RowProcess > 0 then
Begin
n := 1;
for count := 1 to sizeStartThread do
if SGProcess.Cells[2, RowProcess] = startThread[1, count] then
Begin
SGThread.Cells[0, n] := IntToStr(n);
for i := 1 to 3 do
SGThread.Cells[i, n] := startThread[i, count];
Inc(n);
SGThread.RowCount := n + 1;
end;
SGThread.RowCount := n;
end;
{вывод окон}
//очистка рабочей области таблицы
for count := 1 to SGWindow.RowCount - 1 do
SGWindow.Rows[count].Clear;
SGWindow.RowCount := 2;
//если не строка с заголовками столбцов, то:
if RowProcess > 0 then
Begin
n := 1;
for count := 1 to sizeStartWindow do
if SGProcess.Cells[2, RowProcess] = startThread[1, count] then
Begin
SGWindow.Cells[0, n] := IntToStr(n);
for i := 1 to 9 do
SGWindow.Cells[i, n] := startWindow[i, count];
Inc(n);
SGWindow.RowCount := n + 1;
end;
SGWindow.RowCount := n;
end;
//получение списка модулей
if RowProcess > 0 then
Begin
Mmodule.Lines.Clear;
i := 1;
SH := CreateToolHelp32SnapShot(TH32CS_SnapMODULE, StrToInt(SGProcess.Cells[2, RowProcess]));
PME.dwSize := sizeof(ModuleEntry32);
Begin
MModule.Lines.Add(PME.szModule);
Begin
MModule.Lines.Add(PME.szModule);
i := i + 1;
end;
End
else i := 0;
MModule.Lines.Add('Всего модулей: ' + IntToStr(i));
CloseHandle(SH);
end;
end;
procedure TForm1.SGWindowMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
Var
count : Integer;
Chi_hWnd, buflen : longint;
buf : array [0..Max_Char] of Char;
Rect : TRect;
prId,thid : dword;
Begin
SGWindow.MouseToCell(X, Y, ColWindow, RowWindow);
//очистка рабочей области таблицы
for count := 1 to SGChildWindow.RowCount - 1 do
SGChildWindow.Rows[count].Clear;
//если не строка с заголовками столбцов, то:
if RowWindow > 0 then
Begin
//получить список дочерних окон
Chi_hWnd := GetWindow(StrToInt(SGWindow.Cells[1, RowWindow]), GW_CHILD);
count := 0;
SGChildWindow.RowCount := 2;
while Chi_HWnd <> 0 do
Begin
buflen := GetWindowText(Chi_HWnd, @buf, MaX_CHAR);
if buflen > 0 then
Begin
SGChildWindow.Cells[0, count + 1] := IntToStr(count + 1);
SGChildWindow.Cells[1, count + 1] := Format('%10d', [Chi_hWnd]);
SGChildWindow.Cells[2, count + 1] := Format('%s', [String(buf)]);
GetWindowRect(Chi_HWnd,Rect);
thId := GetWindowThreadProcessId(Chi_Hwnd,@Prid);
SGChildWindow.Cells[3, count + 1] := IntToStr(Rect.Left);
SGChildWindow.Cells[4, count + 1] := IntToStr(Rect.Top);
SGChildWindow.Cells[5, count + 1] := IntToStr(Rect.Right);
SGChildWindow.Cells[6, count + 1] := IntToStr(Rect.Bottom);
SGChildWindow.Cells[7, count + 1] := IntToStr(Prid);
SGChildWindow.Cells[8, count + 1] := IntToStr(thid);
if IsWindowVisible(Chi_hWnd) then
SGChildWindow.Cells[9, count + 1] := 'true'
Else
SGChildWindow.Cells[9, count + 1] := 'false';
inc(count);
SGChildWindow.RowCount := count + 1;
end;
Chi_hWnd := GetWindow (Chi_hWnd, GW_HWNDNEXT);
end;
end;
end;
End.
Результат работы программы:
Рис. 1 Результат работы программы.
Мордовский государственный университет имени Н.П.Огарёва
Специальность: АСОИиУ
ЛАБОРАТОРНАЯ РАБОТА
по операционным системам
Получение информации о процессах и потоках
ЛР – 02069964 – ОС – 04 – 12
лабораторная работа № 4
ВЫПОЛНИЛ: ПРОВЕРИЛ:
студенты 241 группы: ____________ 03.04.2012
____________03.04.2012
Алексаев А.Ф. Савкина А.В.
Самылкин А.Д.
Саранск 2012
Практическая часть
1. Реализуйте описанные в лабораторной работе действия с процессами, потоками и окнами:
- для каждого процесса рядом с его именем файла, создавшего процесс, выведите зачение его идентификатора, приоритета и дескриптора (дескриптор процесса можно получить с помощью функции OpenProcess);
- для каждого потока, помимо идентификатора родительского процесса и базового приоритета, выведите идентификатор потока;
- для каждого окна, выведите информацию о его дочерних окнах (дескриптор, заголовок окна, прямоугольник вывода, идентификатор родительского процесса и потока);
- добавьте в компонент StringGrid1, используемый для вывода информации о дочерних окнах, подписи к столбцам.
2. Для выбранного из списка процесса выведите сведения о его потоках, используя компонент StringGrid.
3. Для выбранного из списка процесса постройте список всех созданных им окон с указанием состояния каждого окна (видимое-невидимое), используя компонент StringGrid и функцию IsWindowVisible, которая в качестве параметра принимает дескриптор окна.
4. Добавьте возможность завершения процессов системы (и с ручным вводом идентификатора, и с указанием процесса курсором в окне просмотра ListBox). Не завершайте все подряд, чтобы не перезагружать компьютер.
5. Добавьте возможность изменения приоритета выбранного процесса. Уровень приоритета должен выбираться из списка возможных значений.
Приоритет процесса устанавливается функцией SetPriorityClass, в качестве первого параметра предеается дескриптор процесса. Рекомендуется проверять возвращаемое функцией значение, чтобы убедиться, что желаемое действие выполнено успешно. Функция завершается успешно, если величина возвращаемого значения – не ноль; функция завершается с ошибкой, если величина возвращаемого значения – ноль. Для задания значений приоритета процесса следует использовать символические константы, передавая в функцию SetPriorityClass в качестве второго параметра:
REALTIME_PRIORITY_CLASS,
HIGH_PRIORITY_CLASS,
NORMAL_PRIORITY_CLASS,
IDLE_PRIORITY_CLASS.
6. Добавьте возможность делать доступным или не доступным выбранное окно из списка. Для этого необходимо использовать функцию EnableWindow(hWnd: HWND, bEnable:boolean):Boolean, первый параметр которой hWnd – дескриптор того окна, которое должно быть сделано доступным или недоступным, второй параметр bEnable – задает устанавливаемое значение доступности: true – доступно, false – недоступно.
7. Получите и выведите на экран сведения о модулях, используемых выбранным процессом.
8. Представьте, на основании полученных результатов, дерево процессов.
Листинг 1:
unit Unit1;
Interface
Uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, Grids, TLHelp32, StdCtrls;
Type
TForm1 = class(TForm)
SGProcess: TStringGrid;
SGThread: TStringGrid;
LProcess: TLabel;
LThread: TLabel;
SGWindow: TStringGrid;
LChildWindow: TLabel;
LWindow: TLabel;
SGChildWindow: TStringGrid;
BStartThread: TButton;
BStartWindow: TButton;
EExitProcess: TEdit;
BExitProcess: TButton;
LExitProcess: TLabel;
RBRealtime: TRadioButton;
LPriorityProcess: TLabel;
RBHigh: TRadioButton;
RBNormal: TRadioButton;
RBIdle: TRadioButton;
BPriorityProcess: TButton;
RBWindowBlock: TRadioButton;
RBNoWindowBlock: TRadioButton;
BWindowBlock: TButton;
LWindowBlock: TLabel;
MModule: TMemo;
LModule: TLabel;
procedure FormCreate(Sender: TObject);
procedure SGWindowMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure SGProcessMouseDown(Sender: TObject; Button: TMouseButton;
Shift: TShiftState; X, Y: Integer);
procedure BStartThreadClick(Sender: TObject);
procedure BStartWindowClick(Sender: TObject);
procedure BExitProcessClick(Sender: TObject);
procedure BPriorityProcessClick(Sender: TObject);
procedure BWindowBlockClick(Sender: TObject);
Private
{ Private declarations }
Public
{ Public declarations }
end;
Const
Max_Char=256;
Var
Form1: TForm1;
ColProcess, RowProcess : Integer;
ColWindow, RowWindow : Integer;
startThread : array [1..3, 1..2000] of string;
sizeStartThread : Integer;
startWindow : array [1..9, 1..1000] of string;
sizeStartWindow : Integer;
Implementation
{$R *.dfm}
procedure TForm1.BExitProcessClick(Sender: TObject);
Var
procId,Ex : Cardinal;
Handlep : Thandle;
Begin
if EExitProcess.Text = '' then
Procid:=StrToInt64(SGProcess.Cells[2, RowProcess]) { Окно служит для ручного ввода идентификатора завершаемого процесса }
Else
Procid:=StrToInt64(EExitProcess.Text); { Окно служит для ручного ввода идентификатора завершаемого процесса }
HANDLEp:= OpenProcess( PROCESS_TERMINATE, false, procid );