2010年4月17日土曜日

プロセスリストを表示する。

プロセスの一覧を表示するサンプルです。

Toolhelp32(DelphではTlHelp32)が使える環境では
比較的簡単ですが、

  1. procedure TForm1.Button2Click(Sender: TObject);  
  2. var  
  3.  ProcEntry : TProcessEntry32W;  
  4.    SanpshotHandle : THandle;  
  5. begin  
  6.  //Toolhelp32を使用する例  
  7.    SanpshotHandle := TlHelp32.CreateToolhelp32Snapshot(TlHelp32.TH32CS_SNAPPROCESS,0);  
  8.    if (SanpshotHandle <> -1then  
  9.    begin  
  10.     ListBox1.Items.Clear;  
  11.     ProcEntry.dwSize := Sizeof(TProcessEntry32W);  
  12.       if (TlHelp32.Process32First(SanpshotHandle, ProcEntry)) Then  
  13.       begin  
  14.          repeat  
  15.           ListBox1.Items.Add(ProcEntry.szExeFile);  
  16.          until (TlHelp32.Process32Next(SanpshotHandle,ProcEntry) = false);  
  17.       end;  
  18.    end;  
  19.    CloseHandle(SanpshotHandle);  
  20.   
  21. end;  



使えない環境(といいても、4.0以下のNTだけですが・・・)だと
大変です。



  1. procedure TForm1.Button1Click(Sender: TObject);  
  2. var  
  3.     cb : Cardinal;  
  4.    elements : Cardinal;  
  5.    Needs : Cardinal;  
  6.    ProcIdArray : Array of DWORD;  
  7.    Win32Ret : LongBool;  
  8.    i : Cardinal;  
  9.    ProcHandle : THandle;  
  10.    OpenMode : THandle;  
  11.    ProcessName : String;  
  12.   
  13. begin  
  14.   
  15.     //プロセス数がいくつあるか解らないので大きめにとっておく  
  16.    elements := 128;  
  17.    Needs := elements * Sizeof(DWORD);  
  18.    cb := 0;  
  19.    while (cb <= Needs) do  
  20.    begin  
  21.   
  22.         SetLength(ProcIdArray, elements);  
  23.        cb := Length(ProcIdArray) * Sizeof(DWORD);  
  24.        Needs := 0;  
  25.       Win32Ret := PsApi.EnumProcesses(PDWORD(ProcIdArray),cb,Needs);  
  26.   
  27.       //APIが失敗したら抜ける  
  28.       if (not(Win32Ret)) then  
  29.       begin  
  30.          break;  
  31.       end;  
  32.   
  33.       //領域が足りなかったときに備えて倍にする。  
  34.       elements := elements * 2;  
  35.   
  36.    end;  
  37.   
  38.    if (Win32Ret) then  
  39.    begin  
  40.        ListBox1.Items.Clear;  
  41.       OpenMode := Windows.PROCESS_QUERY_INFORMATION or Windows.PROCESS_VM_READ;  
  42.         elements := Needs div Sizeof(DWORD);  
  43.        for i := 0 to elements - 1 do  
  44.        begin  
  45.           //プロセスIDから情報をえる  
  46.          ProcHandle := Windows.OpenProcess(OpenMode,FALSE,ProcIdArray[i]);  
  47.          if (ProcHandle <> 0then  
  48.          begin  
  49.              ProcessName := GetProcessName(ProcHandle);  
  50.             if (Length(ProcessName) > 0then  
  51.             begin  
  52.                 ListBox1.Items.Add(ProcessName);  
  53.             end;  
  54.          end;  
  55.          Windows.CloseHandle(ProcHandle);  
  56.       end;  
  57.    end;  
  58.   
  59. end;  
  60.   
  61. function TForm1.GetProcessName(ProcessHandle: THandle): String;  
  62. var  
  63.     cb : Cardinal;  
  64.    elements : Cardinal;  
  65.    Needs : Cardinal;  
  66.    ModuleHandleArray : Array of THandle;  
  67.    Win32Ret : LongBool;  
  68.    i : longint;  
  69.    ModuleHandle: THandle;  
  70.    ModuleName : WideString;  
  71.    ModeleNameLength : Integer;  
  72.    ProcessName : String;  
  73.    FileExt : String;  
  74. begin  
  75.   
  76.     Result := '';  
  77.     //モジュール数数がいくつあるか解らないので大きめにとっておく  
  78.    elements := 128;  
  79.    Needs := elements * Sizeof(DWORD);  
  80.    cb := 0;  
  81.    while (cb <= Needs) do  
  82.    begin  
  83.   
  84.         SetLength(ModuleHandleArray, elements);  
  85.        cb := Length(ModuleHandleArray) * Sizeof(DWORD);  
  86.        Needs := 0;  
  87.       Win32Ret := PsApi.EnumProcessModules(ProcessHandle,PDWORD(ModuleHandleArray),cb,Needs);  
  88.   
  89.       //APIが失敗したら抜ける  
  90.       if (not(Win32Ret)) then  
  91.       begin  
  92.          break;  
  93.       end;  
  94.       //領域が足りなかったときに備えて倍にする。  
  95.       elements := elements * 2;  
  96.    end;  
  97.   
  98.    if (Win32Ret) then  
  99.    begin  
  100.        ModeleNameLength := 255;  
  101.       SetLength(ModuleName,ModeleNameLength);  
  102.         elements := Needs div Sizeof(DWORD);  
  103.        for i := 0 to elements - 1 do  
  104.        begin  
  105.           ModuleHandle := ModuleHandleArray[i];  
  106.           ModeleNameLength := PsApi.GetModuleBaseName(  
  107.                                   ProcessHandle,  
  108.                                 ModuleHandle,  
  109.                                 PWideChar(ModuleName),  
  110.                                 ModeleNameLength);  
  111.          if (ModeleNameLength > 0then  
  112.          begin  
  113.              //モジュール名がExeファイルであればプロセスとみなす。  
  114.              SetLength(ModuleName,ModeleNameLength);  
  115.             ProcessName := ModuleName;  
  116.             FileExt := ExtractFileExt(ProcessName);  
  117.             if (CompareText(FileExt,'.EXE') = 0)  then  
  118.             begin  
  119.                 Result :=  ProcessName;  
  120.                break;  
  121.             end;  
  122.          end;  
  123.       end;  
  124.    end;  
  125. end;  

0 件のコメント: