2009-07-09 14 views
6

Jak uzyskać listę uruchomionych procesów (ze szczegółami PID, właściciela itp.) Na moim komputerze za pomocą Delphi?Wyliczenie uruchomionych procesów w Delphi

EDIT: Żaden z proponowanych rozwiązań daje mi użytkownika, który jest właścicielem procesu, tylko informacje takie jak PID, nazwa_exe itp ...

+1

Powinieneś użyć JCL zaproponowanego poniżej. Bezpośrednie korzystanie z funkcji toolhelp lub EnumProcesses jest dość kłopotliwe. –

Odpowiedz

10

Jednym ze sposobów jest użycie Tool Help library (patrz jednostka TlHelp32) lub EnumProcesses w systemie Windows NT (patrz urządzenie PSAPI). Spójrz na przykład na JclSysInfo.RunningProcessesList w JCL.

Oto krótki przykład jak uzyskać nazwę użytkownika procesu:

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

Niestety, to nie rozwiązuje mojej potrzeby znalezienia właściciela procesu. – Marius

+0

Korzystanie z biblioteki pomocy narzędzia zawiera zwrócone wpisy w polu th32ParentProcessID. Sam JclSysInfo tego nie używa, ale możesz go użyć jako punktu wyjścia. –

+0

TOndrej - Tak naprawdę myślałem o użytkowniku, który jest właścicielem/prowadzi proces – Marius

3

Jest to funkcja używamy, aby sprawdzić, czy proces istnieje, FProcessEntry32 posiada wszystkie informacje na temat tego procesu, tak powinieneś być w stanie rozszerzyć go do tego, czego potrzebujesz.

została ona podjęta z 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; 

Rekord TProcessEntry32 wygląda tak:

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

Dzięki za kod, działa świetnie. BTW, możesz zamienić tę klauzulę if na 'if StrUtils.EndsText (exeFileName, FProcessEntry32.szExeFile) then'. – saastn

2

This class will give you a list of all open windows (wymienione poniżej) z PID, podpis, wymiary, itp nie jest to dokładnie bieżącą informację procesów , ale użyłem go do znalezienia aplikacji za jego pośrednictwem.

// 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. 
Powiązane problemy