Вопрос по delphi, winapi – Перечислите запущенные процессы в Delphi

7

Как получить список запущенных процессов (с указанием PID, владельца и т. Д.) На моей машине с помощью Delphi?

EDIT: Ни одно из предложенных решений не дает мне пользователя, которому принадлежит процесс, только такую информацию, как PID, ExeName и т. Д.

Вы должны использовать JCL, предложенный ниже. Непосредственное использование функций toolhelp или EnumProcesses является довольно сложной задачей. Daniel Rikowski

Ваш Ответ

6   ответов
2

Этот класс даст вам список всех открытых окон (перечислены ниже) с PID, заголовком, размерами и т. д. Он не точно выполняет информацию о процессах, но я использовал ее для поиска приложений через нее.

//   Window List Component 1.//
//   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.
3

которую мы используем, чтобы проверить, существует ли процесс, FProcessEntry32 хранит всю информацию о процессе, поэтому вы сможете расширить его до того, что вам нужно.

это было взято изВот

  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;
Спасибо за код, он отлично работает. Кстати, вы можете заменить это, если пункт сif StrUtils.EndsText(exeFileName, FProcessEntry32.szExeFile) then.
1

Компоненты WMISet (Одна лицензия на 69 долларов, лицензия на сайт - 199 долларов, доступна пробная версия).Компонент TWmiProcessControl кажется, инкапсулирует вызовы Win32_Process. У них также есть примерполучить владельца процесса.

3

CreateToolhelp32Snapshot Function Process32First Function Process32Next Function

PROCESSENTRY32 Структура будет содержать всю информацию, которая может вам понадобиться.

Документация от MDSN для C ++, но этоsame в Дельфи.

11

Библиотека справки по инструментам (см. блок 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;
Понимаю. Я предположил, что "владельцем" Вы имели в виду родительский процесс. Я добавил код, чтобы получить имя пользователя учетной записи, под которой запущен процесс.
К сожалению, это не решает мою проблему с поиском владельца процесса Marius
TOndrej - я на самом деле думал о пользователе, который владеет / управляет процессом Marius
Используя библиотеку справки инструмента, в возвращаемых записях есть поле th32ParentProcessID. Сам JclSysInfo не использует его, но вы можете использовать его в качестве отправной точки.
1

Madshi madKernel может быть интересно проверить.

Да, очень рекомендуется.

Похожие вопросы