Thema: Delphi EnumProcesses

Einzelnen Beitrag anzeigen

Benutzerbild von Luckie
Luckie

Registriert seit: 29. Mai 2002
37.621 Beiträge
 
Delphi 2006 Professional
 
#1

EnumProcesses

  Alt 4. Dez 2004, 04:13
Ich versuche gerade eine Prozessliste mit EnumProcesses zu bekommen. Ich habe da schon eine funktionierden Version auf meiner HP, wollte es aber besser machen:
Delphi-Quellcode:
function GetProcessList(out ProcessList: TProcessList): DWORD;

  function GetOSVersionInfo(var Info: TOSVersionInfo): Boolean;
  begin
    FillChar(Info, SizeOf(TOSVersionInfo), 0);
    Info.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
    Result := GetVersionEx(TOSVersionInfo(Addr(Info)^));
    if (not Result) then
    begin
      FillChar(Info, SizeOf(TOSVersionInfo), 0);
      Info.dwOSVersionInfoSize := SizeOf(TOSVersionInfo);
      Result := GetVersionEx(TOSVersionInfo(Addr(Info)^));
      if (not Result) then
        Info.dwOSVersionInfoSize := 0;
    end;
  end;

var
  OSInfo : TOSVersionInfo;
  PidProcesses : PDWORD;
  PidWork : PDWORD;
  BufferSize : Cardinal;
  cbNeeded : Cardinal;
  cntProcesses : Cardinal;
  i : Cardinal;

begin
  result := 0;

  // What OS are we running on?
  if GetOSVersionInfo(OSInfo) then
  begin
    if (OSInfo.dwPlatformId = VER_PLATFORM_WIN32_NT) and (OSInfo.dwMajorVersion =
      5) then
    // WinNT and higher
    begin
      cbNeeded := 0;
      BufferSize := 0;
      // how much memory do we need
      if EnumProcesses(nil, BufferSize, cbNeeded) then
      begin
        cntProcesses := cbNeeded div sizeof(DWORD);
        GetMem(PidProcesses, cntProcesses);
        if EnumProcesses(PidProcesses, cntProcesses, cbNeeded) then
        begin
          PidWork := PidProcesses;
          setlength(ProcessList, cntProcesses);
          for i := 0 to cntProcesses - 1 do
          begin
            ProcessList[i] := PidWork^;
            Inc(PidWork, sizeof(PDWORD));
          end;
        end;
        FreeMem(PidProcesses, cntProcesses);
      end;
    end
    // Win 9x and higher except WinNT
    else
    begin
    end;
  end;
end;
Im PSDK steht:
Zitat:
To determine how many processes were enumerated by the call to EnumProcesses, divide the resulting value in the cbNeeded parameter by sizeof(DWORD).
Ich dachte mit dem ersten Aufruf füllt er mir cbNeeded. Tut er aber nicht, ist immer null.

Mache ich es so:
Delphi-Quellcode:
procedure TForm1.Button1Click(Sender: TObject);
var
  pdwResult : PDWORD; // für den Buffer
  pdwWork : PDWORD; // um dem Buffer verarbeiten zu können
  dwCountIn : DWORD; // Grösse des Buffers in Byte
  dwCountOut : DWORD; // Zurückgelieferte Anzahl Byte
  i : integer;
begin
  dwCountOut := 0; // Sicherheitshalber initialisieren, muss nicht sein
  dwCountIn := 1024; // Willkürlich gewählt, genügt für 256 Prozesse
  pdwResult := AllocMem(dwCountIn);
  try
    if not EnumProcesses(pdwResult,dwCountIn,dwCountOut) then begin
      RaiselastOSError();
    end else begin
      pdwWork := pdwResult; // zur Verarbeitung übergeben, damit FreeMem funktioniert
      for i := 1 to (dwCountOut shr 2) do begin // shr 2 = / 4, da 4 Byte je DWORD
        // Prozess Id ausgeben
        //ShowMessage('ProzessId# '+IntToStr(i)+': '+IntToStr(pdwWork^));
        ListBox1.Items.Add(GetProcessName(pdwWork^));
        // auf nächste addressieren (inc erhöht automatisch um 4, da es ein typisierter Pointer ist
        inc(pdwWork);
      end;
    end;
  finally
    FreeMem(pdwResult,dwCountIn);
  end;
end;
Dann geht es. Nur finde ich es etwas blöd unnötig Speicher zu reservieren.
Michael
Ein Teil meines Codes würde euch verunsichern.
  Mit Zitat antworten Zitat