2009-07-09 71 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.