トップへ(mam-mam.net/)

プロセス一覧取得と強制終了 ~Delphiソースコード集

プロセス一覧取得と強制終了 ~Delphiソースコード集

DelphiでQueryFullProcessImageNameW APIでプロセス一覧を取得して表示し、
TerminateProcess APIで選択したプロセスIDを強制終了させる方法をサンプルソースコードで解説します。

フォームデザイン

IDEから[ファイル]⇒[新規作成]⇒[VLC フォーム アプリケーション - Delphi]を選択して新規プロジェクトを作成します。
TButton × 2個をドラッグ&ドロップし、TStringGrid × 1個をドラッグ&ドロップします。

ソースコード

以下ソースコードを貼り付けた後、デザインビューの左ペインのオブジェクトインスペクタのイベントから
Form1.OnCerate に FormCreate を、
Button1.OnClick に Button1Click を、
Button2.Onclick に Button2Click を設定します。

unit Unit1;

interface

uses
  Winapi.Windows, Winapi.Messages, System.SysUtils, System.Variants, System.Classes,
  Vcl.Graphics, Vcl.Controls, Vcl.Forms, Vcl.Dialogs, Vcl.StdCtrls, Vcl.Grids;

type
  TForm1 = class(TForm)
    Button1: TButton;
    Button2: TButton;
    StringGrid1: TStringGrid;
    procedure Button1Click(Sender: TObject);
    procedure Button2Click(Sender: TObject);
    procedure FormCreate(Sender: TObject);
  private
    { Private 宣言 }
    //プロセス一覧取得
    procedure GetProcessList(StrGrid: TStringGrid);
  public
    { Public 宣言 }
  end;

function QueryFullProcessImageNameW(
  hProcess   : THandle;
  dwFlags    : DWORD;
  lpExeName  : PWideChar;
  var dwSize : DWORD
): BOOL; stdcall; external kernel32 name 'QueryFullProcessImageNameW';

function QueryFullProcessImageNameA(
  hProcess: THandle;
  dwFlags: DWORD;
  lpExeName: PAnsiChar;
  var lpdwSize: DWORD
): BOOL; stdcall; external kernel32 name 'QueryFullProcessImageNameA';


var
  Form1: TForm1;

const
  PROCESS_QUERY_LIMITED_INFORMATION=$1000;
  LVM_FIRST     = $1000;
  LVM_GETHEADER = LVM_FIRST + 31;

implementation

{$R *.dfm}

uses Winapi.TlHelp32;

procedure TForm1.Button1Click(Sender: TObject);
begin
  //プロセス一覧取得
  GetProcessList(StringGrid1);
end;

procedure TForm1.Button2Click(Sender: TObject);
var
  ProcessID   : DWORD;
  hProcHandle : THandle;
begin
  //選択されていなければなにもしない
  if StringGrid1.Row < 1 then exit;
  if Trim(StringGrid1.Cells[0,StringGrid1.Row])='' then exit;
  //選択されているプロセスID
  ProcessID := StrToInt(StringGrid1.Cells[0,StringGrid1.Row]);
  //プロセスを終了する為にプロセスを開いてハンドルを取得

  if Application.MessageBox(
      PChar('プロセスID'+IntToStr(ProcessID)+'を強制終了させます'),
      '確認',MB_OKCANCEL
      )<>ID_OK then exit;

  hProcHandle := OpenProcess(PROCESS_TERMINATE, False, ProcessID);
  try
    //プロセスの終了
    TerminateProcess(hProcHandle, 0);
  finally
    //ハンドルを閉じる
    CloseHandle(hProcHandle);
  end;
  //プロセス一覧取得
  GetProcessList(StringGrid1);
end;


procedure TForm1.FormCreate(Sender: TObject);
begin
  StringGrid1.RowCount:=2;
  StringGrid1.ColCount:=3;
  StringGrid1.Rows[0].CommaText:='PID,ファイル名,スレッド数';
  StringGrid1.FixedCols:=0;
  StringGrid1.FixedRows:=1;
  StringGrid1.ColWidths[0]:=64;
  StringGrid1.ColWidths[1]:=256;
  StringGrid1.ColWidths[2]:=64;
  StringGrid1.Options:=StringGrid1.Options+[TGridOption.goRowSelect];

  Button1.Caption:='プロセス一覧表示';
  Button2.Caption:='プロセス強制終了';
end;

procedure TForm1.GetProcessList(StrGrid: TStringGrid);
var
  hSnapShot: THandle;
  ProcEntry: TProcessEntry32;
  hProcHandle : THandle;
  Buff        : array[0..MAX_PATH-1] of Char;
  STR_SIZE    : DWORD;
  fullpath:String;
  Count:Integer;
begin
  Count:=1;
  //引数 TH32CS_SNAPPROCESS:全プロセスをスナップショットに含む
  //     0:現在プロセスも含める(スナップショットに含めるプロセスのプロセス識別子)
  hSnapShot := CreateToolHelp32Snapshot(TH32CS_SNAPPROCESS, 0);
  if hSnapShot = INVALID_HANDLE_VALUE then Exit;
  ProcEntry.dwSize := SizeOf(ProcEntry);
  if Process32First(hSnapShot, ProcEntry) then
  begin
    repeat
      //プロセスID値からプロセスのオープンハンドルを取得
      hProcHandle := OpenProcess(
        PROCESS_QUERY_LIMITED_INFORMATION, False, ProcEntry.th32ProcessID
      );
      try
        STR_SIZE := Length(Buff);
        fullpath:='';
        if QueryFullProcessImageNameW(hProcHandle,0,PWideChar(@Buff),STR_SIZE) then
        begin
          fullpath:=String(Buff);
        end;
      finally
        CloseHandle(hProcHandle);
      end;
      StrGrid.RowCount:=Count+1;
      StrGrid.Cells[0,Count]:=IntToStr(ProcEntry.th32ProcessID);
      if fullpath='' then
      begin
        StrGrid.Cells[1,Count]:=ProcEntry.szExeFile;
      end
      else
      begin
        StrGrid.Cells[1,Count]:=fullpath;
      end;
      StrGrid.Cells[2,Count]:=IntToStr(ProcEntry.cntThreads);
      inc(Count);
    until not Process32Next(hSnapShot, ProcEntry);
  end;
  CloseHandle(hSnapShot);
end;

end.

実行

IDEから[実行]⇒[実行]を選択するとコンパイルされて実行されます。
Button1をクリックするとプロセス一覧が表示され、StringGrid1からプロセスを選択してButton2をクリックするとプロセスが強制終了されます。