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.

Результат работы программы:

Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms - student2.ru

Рис. 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 );

Наши рекомендации