Delphi Tips 
-----------------------------

0051  D1   D2   D3   D4   D5   D6   D7   3.1   95   98    作成: 1999/02/08 osamu rev 1.4
   B1   B3   B4   B5   B6   B7   NT3   NT4   2K   XP  更新: 1999/08/23 西坂良幸 編集
WinNT でウィンドウハンドルから実行アプリ名を知る

WinNT では、ToolHelp32 が使えないので、Win95 で良く知られた方法(ToolHelp32)は使えません。
  http://www.microsoft.com/japan/support/kb/articles/J041/6/32.htm

に、Win95/NT 両方で使える方法が C 言語で書かれてます。

ここでは、PSAPIを使っています。
上記の部分的丸写しですが。

uses PsApi;

type
  TEnumProcs = function(ID: DWord; Str: PChar; LP:  LParam):bool; stdcall;

procedure EnumProcessesNT(lpEnumFunc: TEnumProcs; lParam: longint);
var
  // 関数ポインタ
  EnumProcesses: TEnumProcesses;
  EnumProcessModules: TEnumProcessModules;
  GetModuleFileNameEx: TGetModuleFileNameEx;
  // 変数
  hLib: THandle;
  Process: THandle;
  hMod: DWORD;
  PIDs: array[0..2047] of DWORD; // 動的配列ポインタの扱いを簡素化(^^;
  Size, Size2, Index: DWORD;
  ProcessName: array[0..MAX_PATH] of char;
begin
  hMod := 0;
  // PSAPI.DLL のロード
  hLib := LoadLibraryA('PSAPI.DLL');
  if hLib = 0 then
   raise Exception.Create('PSAPI.DLL がロードできません。');
  // API のアドレス取得(以下の3個を使う)
  EnumProcesses := TEnumProcesses(GetProcAddress(hLib, 'EnumProcesses'));
  EnumProcessModules := TEnumProcessModules(GetProcAddress(hLib, 'EnumProcessModules'));
  GetModuleFileNameEx := TGetModuleFileNameEx(GetProcAddress(hLib, 'GetModuleFileNameExA'));
  // ロードのチェック
  if (not Assigned(EnumProcesses))
     or(not Assigned(EnumProcessModules))
     or(not Assigned(GetModuleFileNameEx)) then
   begin
     FreeLibrary(hLib);
     raise Exception.Create('API のアドレスを取得できません。');
   end;
  // プロセスの数は2048まで
  Size2 := 2048 * SizeOf(DWORD);
  if not EnumProcesses(@PIDs, Size2, Size) then
  begin
     FreeLibrary(hLib);
     raise Exception.Create(SysErrorMessage(GetLastError));
  end;
  if Size >= Size2 then
  begin
    FreeLibrary(hLib);
    raise Exception.Create('2048 個以上のプロセスがあるみたいです。');
  end;
  Size := Size div SizeOf(DWORD);
  for Index := 0 to Size - 1 do
  begin
    // プロセスを読み出す
    Process := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ,
        False, PIDs[Index]);
    if Process <> 0 then
    begin
      // プロセスのモジュールをチェック
      if EnumProcessModules(Process, PDWORD(hMod), SizeOf(hMod), Size2) then
      begin
        // ファイル名を取得
        if GetModuleFileNameEx(Process, hMod, ProcessName, SizeOf(ProcessName)) = 0 then
        begin
          ProcessName:='';
        end;
      end;
      CloseHandle(Process);
    end
    else
      ProcessName:='';
    // コールバック関数を呼び出し
    if not lpEnumFunc(PIDs[Index], ProcessName, lParam) then
    else Break;
  end;
  // 解放
  FreeLibrary(hLib);
end;

// 使用例
function CallBackTest(ID: DWord; Str: PChar; LP: LParam):bool;stdcall;
begin
  TListBox(LP).Items.Addobject(Str,Pointer(ID));
  Result := True;
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
  ListBox1.Items.Clear;
  EnumProcessesNT(@CallBackTest,Longint(ListBox1));
  // リストボックスに列挙する
end;


参照: [Delphi-ML:19427] <Windows>

[新規作成] [最新の情報に更新]

How To
Lounge
KeyWords


Tips
Delphi
Home
Osamu Takeuchi osamu@big.or.jp