2009-07-09 44 views
6

Làm cách nào để có danh sách các tiến trình đang chạy (với các chi tiết về PID, Chủ sở hữu, vv) trên máy của tôi bằng Delphi?Liệt kê các tiến trình đang chạy trong Delphi

EDIT: Không ai trong số các giải pháp đề xuất mang lại cho tôi người dùng sở hữu quá trình, chỉ có thông tin như PID, ExeName vv ...

+1

Bạn nên sử dụng JCL được đề xuất bên dưới. Trực tiếp sử dụng công cụ trợ giúp hoặc các hàm EnumProcesses khá phức tạp. –

Trả lời

10

Một cách đang sử dụng Tool Help library (xem đơn vị TlHelp32) hoặc EnumProcesses trên Windows NT (xem đơn vị PsAPI). Hãy xem JclSysInfo.RunningProcessesList trong ví dụ JCL.

Dưới đây là một ví dụ nhanh như thế nào để có được tên người dùng của một quá trình:

type 
    PTokenUser = ^TTokenUser; 
    TTokenUser = packed record 
    User: SID_AND_ATTRIBUTES; 
    end; 

function GetProcessUserName(ProcessID: Cardinal; out DomainName, UserName: string): Boolean; 
var 
    ProcessHandle, ProcessToken: THandle; 
    InfoSize, UserNameSize, DomainNameSize: Cardinal; 
    User: PTokenUser; 
    Use: SID_NAME_USE; 
    _DomainName, _UserName: array[0..255] of Char; 
begin 
    Result := False; 
    DomainName := ''; 
    UserName := ''; 

    ProcessHandle := OpenProcess(PROCESS_QUERY_INFORMATION or PROCESS_VM_READ, False, ProcessID); 
    if ProcessHandle = 0 then 
    Exit; 

    try 
    if not OpenProcessToken(ProcessHandle, TOKEN_QUERY, ProcessToken) then 
     Exit; 

    try 
     GetTokenInformation(ProcessToken, TokenUser, nil, 0, InfoSize); 
     User := AllocMem(InfoSize * 2); 
     try 
     if GetTokenInformation(ProcessToken, TokenUser, User, InfoSize * 2, InfoSize) then 
     begin 
      DomainNameSize := SizeOf(_DomainName); 
      UserNameSize := SizeOf(_UserName); 

      Result := LookupAccountSid(nil, User^.User.Sid, _UserName, UserNameSize, _DomainName, DomainNameSize, Use); 

      if Result then 
      begin 
      SetString(DomainName, _DomainName, StrLen(_DomainName)); 
      SetString(UserName, _UserName, StrLen(_UserName)); 
      end; 
     end; 
     finally 
     FreeMem(User); 
     end; 
    finally 
     CloseHandle(ProcessToken); 
    end; 
    finally 
    CloseHandle(ProcessHandle); 
    end; 
end; 
+0

Thật không may, điều này không giải quyết được nhu cầu của tôi về việc tìm kiếm chủ sở hữu của quá trình – Marius

+0

Sử dụng thư viện Trợ giúp Công cụ, có trường th32ParentProcessID trong các mục được trả về. Bản thân JclSysInfo không sử dụng nó nhưng bạn có thể sử dụng nó như là một điểm khởi đầu. –

+0

TOndrej - Tôi đã thực sự nghĩ đến người dùng sở hữu/chạy quy trình – Marius

3

Đây là chức năng chúng tôi sử dụng để kiểm tra xem một quá trình tồn tại, FProcessEntry32 nắm giữ tất cả các thông tin về quy trình, vì vậy bạn sẽ có thể mở rộng nó đến những gì bạn cần.

nó được lấy từ here

uses TlHelp32 

function processExists(exeFileName: string): Boolean; 
{description checks if the process is running 
URL: http://www.swissdelphicenter.ch/torry/showcode.php?id=2554} 
var 
    ContinueLoop: BOOL; 
    FSnapshotHandle: THandle; 
    FProcessEntry32: TProcessEntry32; 
begin 
    FSnapshotHandle  := CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0); 
    FProcessEntry32.dwSize := SizeOf(FProcessEntry32); 
    ContinueLoop   := Process32First(FSnapshotHandle, FProcessEntry32); 
    Result := False; 


    while Integer(ContinueLoop) <> 0 do 
    begin 

    if ((UpperCase(ExtractFileName(FProcessEntry32.szExeFile)) = 
     UpperCase(ExeFileName)) or (UpperCase(FProcessEntry32.szExeFile) = 
     UpperCase(ExeFileName))) then 
    begin 
     Result := True; 
    end; 

    ContinueLoop := Process32Next(FSnapshotHandle, FProcessEntry32); 
    end; 
    CloseHandle(FSnapshotHandle); 
end; 

Biên TProcessEntry32 trông giống như vậy:

tagPROCESSENTRY32 = packed record 
    dwSize: DWORD; 
    cntUsage: DWORD; 
    th32ProcessID: DWORD;  // this process 
    th32DefaultHeapID: DWORD; 
    th32ModuleID: DWORD;  // associated exe 
    cntThreads: DWORD; 
    th32ParentProcessID: DWORD; // this process's parent process 
    pcPriClassBase: Longint; // Base priority of process's threads 
    dwFlags: DWORD; 
    szExeFile: array[0..MAX_PATH - 1] of Char;// Path 
    end; 
+0

Cảm ơn mã, nó hoạt động rất tốt. BTW, bạn có thể thay thế mệnh đề if đó bằng 'if StrUtils.EndsText (exeFileName, FProcessEntry32.szExeFile) rồi'. – saastn

2

This class will give you a list of all open windows (liệt kê dưới đây) với PID, chú thích, kích thước, vv Nó không hẳn là chạy thông tin quá trình , nhưng tôi đã sử dụng nó để tìm các ứng dụng thông qua nó.

// Window List Component 1.5 by Jerry Ryle 
// 
// Aaugh! I accidentally uploaded the wrong source 
// which had a nasty bug in the refresh procedure! 
// Thanks to Serge, who found my mistake and suggested 
// a few other improvements! 
// 
// This component will enumerate windows and return 
// information about them in the Windows property. 
// The component currently returns a handle, caption text, 
// associated ProcessID, visibility, and dimensions. 
// For documentation, please read the accompanying 
// WindowList.txt 
// 
// This component is completely free of course. If you find 
// it useful, and are compelled to send me cash, beer, or 
// dead things in envelopes, please feel free to do so. 
// 
// email me if you make it better: [email protected] 

unit WindowList; 

interface 

uses 
    Windows, Messages, SysUtils, Classes, Graphics, Controls, Forms, Dialogs; 

type 

    TWindowObject = record 
        WinHandle : HWnd; // Window Handle 
        WinCaption : String; // Window Caption Text (If any) 
        ProcessID : Integer; // Process the window belongs to 
        IsVisible : Boolean; // Is the window visible? 
        IsEnabled : Boolean; // Is the window enabled for mouse/keyboard input? 
        IsIconic : Boolean; // Is the window minimized? 
        WindowRect : TRect; // Window Dimensions 
        // Add more properties here if you like, 
        // then fill them in at the WindowCallback 
        // function. 
        end; 
    PTWindowObject = ^TWindowObject; 

    TWindowList = class(TComponent) 
    private 
    WindowLst : TList; 
    FCount : Integer; 
    protected 
    Function GetAWindow(Index : Integer) : TWindowObject; 
    public 
    constructor Create(AOwner: TComponent); override; 
    destructor Destroy; override; 

    Procedure Refresh; 
    Property Windows[Index : Integer]: TWindowObject read GetAWindow; 
    Property Count : Integer read FCount; 
    published 
    // Published declarations 
    end; 

procedure Register; 

implementation 

// Note that this function is not a member of WindowList. 
// Therefore, the list to be filled needs to be passed 
// as a pointer. Note that this is passed as a VAR. if you 
// don't do this, bad things happen in memory. 

Function WindowCallback(WHandle : HWnd; Var Parm : Pointer) : Boolean; stdcall; 
// This function is called once for each window 
Var MyString : PChar; 
    MyInt : Integer; 
    MyWindowPtr : ^TWindowObject; 
begin 
    New(MyWindowPtr); 

    // Window Handle (Passed by the enumeration) 
    MyWindowPtr.WinHandle := WHandle; 

    // Window text 
    MyString := Allocmem(255); 
    GetWindowText(WHandle,MyString,255); 
    MyWindowPtr.WinCaption := String(MyString); 
    FreeMem(MyString,255); 

    // Process ID 
    MyInt := 0; 
    MyWindowPtr.ProcessID := GetWindowThreadProcessId(WHandle,@MyInt); 

    // Visiblity 
    MyWindowPtr.IsVisible := IsWindowVisible(WHandle); 

    // Enabled 
    MyWindowPtr.IsEnabled := IsWindowEnabled(WHandle); 

    // Iconic 
    MyWindowPtr.IsIconic := IsIconic(WHandle); 

    // Window Dimensions 
    MyWindowPtr.WindowRect := Rect(0,0,0,0); 
    GetWindowRect(WHandle,MyWindowPtr.WindowRect); 

    // Add the structure to the list. Do not dereference Parm... 
    // once again, bad things happen. 
    TList(Parm).Add(MyWindowPtr); 
    Result := True; // Everything's okay. Continue to enumerate windows 
end; 

constructor TWindowList.Create(AOwner: TComponent); 
var MyWindowPtr : PTWindowObject; 
begin 
    inherited; 
    WindowLst := TList.Create; 

    // Thanks Serge, I should've done this from the start :) 
    // Sloppy me. 
    If Not (csDesigning in ComponentState) Then 
    Begin 
     EnumWindows(@WindowCallback,Longint(@WindowLst)); 
     FCount := WindowLst.Count; 
    End 
    Else 
    FCount := 0; 
end; 

destructor TWindowList.Destroy; 
var I : Integer; 
begin 
    If WindowLst.Count > 0 Then 
    Begin 
     For I := 0 To (WindowLst.Count - 1) Do 
     Dispose(PTWindowObject(WindowLst[I])); 
    End; 
    WindowLst.Free; 
    inherited; 
end; 

procedure TWindowList.Refresh; 
begin 
    WindowLst.Clear; {Clear the list!} 
    EnumWindows(@WindowCallback,Longint(@WindowLst)); 
    FCount := WindowLst.Count; 
end; 

function TWindowList.GetAWindow(Index : Integer) : TWindowObject; 
begin 
    Result := PTWindowObject(WindowLst[Index])^; 
end; 

procedure Register; 
begin 
    RegisterComponents('System', [TWindowList]); 
end; 

end. 
Các vấn đề liên quan