2009-07-09 67 views
6

如何在我的機器上使用Delphi獲取正在運行的進程(包括PID,所有者等詳細信息)的列表?枚舉Delphi中的運行進程

編輯:沒有提出解決方案,讓我擁有這個過程中,只有信息,如PID,EXENAME等必須使用的用戶...

+1

您應該使用下面提出的JCL。直接使用toolhelp或EnumProcesses函數是相當麻煩的。 – 2009-07-09 08:23:00

回答

10

一種方法是在Windows NT上使用Tool Help library(請參閱TlHelp32單元)或EnumProcesses(請參閱PsAPI單元)。例如,在JCL中查看JclSysInfo.RunningProcessesList

這裏有一個如何得到一個進程的用戶名一個簡單的例子:

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

不幸的是,這並沒有解決我尋找進程所有者的需求。 – Marius 2009-07-09 08:43:01

+0

使用工具幫助庫,返回的條目中有th32ParentProcessID字段。 JclSysInfo本身並不使用它,但可以用它作爲起點。 – 2009-07-09 08:53:59

+0

TOndrej - 我實際上正在考慮擁有/運行我看過程 – Marius 2009-07-09 09:00:32

3

這是我們用來檢查一個進程存在的功能,FProcessEntry32擁有所有的過程信息,所以你應該能夠把它擴展到你所需要的東西。

它從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; 

採取的TProcessEntry32記錄看起來像這樣:

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; 
2

This class will give you a list of all open windows與PID,標題,尺寸等,這是不完全運行的進程信息(見下表) ,但我用它通過它來查找應用程序。

// 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.