代码之家  ›  专栏  ›  技术社区  ›  AviD

在Delphi中枚举正在运行的进程

  •  7
  • AviD  · 技术社区  · 15 年前

    如何获得使用Delphi的机器上正在运行的进程的列表(包括PID、所有者等的详细信息)?

    编辑: 所有的解决方案都没有给我拥有进程的用户,只有PID、exename等信息…

    6 回复  |  直到 15 年前
        1
  •  11
  •   Ondrej Kelle    15 年前

    一种方法是使用 Tool Help library (见TLhelp32单元),或 EnumProcesses 在Windows NT上(请参阅PSAPI单元)。看一看 JclSysInfo.RunningProcessesList JCL 举个例子。

    下面是如何获取进程用户名的快速示例:

    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;
    
        2
  •  3
  •   Nick Dandoulakis    15 年前

    你必须使用:

    PROCESSENTRY32 Structure 将包含您可能需要的所有信息。

    文档来自MDSN,用于C++,但它是 相同的 在Delphi中。

        3
  •  3
  •   Re0sless    15 年前

    这是我们用来检查流程是否存在的功能,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;
    
        4
  •  2
  •   Pauk    15 年前

    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:  gryle@calpoly.edu
    
    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.
    
        5
  •  1
  •   Pauk    15 年前

    你可以用 WMISet components (69美元一张许可证,199美元现场许可证,试用版可用)。这个 TWmiProcessControl component 似乎封装了对win32_进程的调用。他们也有一个例子 getting a process owner .

        6
  •  1
  •   Vegar    15 年前

    我想 Madshi madKernel 可能会很有趣。