Announcement

Collapse
No announcement yet.

Bestimmten Prozess finden

Collapse
X
  • Filter
  • Time
  • Show
Clear All
new posts

  • Bestimmten Prozess finden

    Im Taskmanager von NT/2000 unter Prozesse sieht man die laufenden Prozesse.
    Wie kann ich von Delphi aus einen bestimmten Prozess finden? Konkret möchte ich herausfinden, ob z.B. der Prozess 'Wsview41.exe' vorhanden ist.

    Besten Dank.

  • #2
    <i><font color=green>{ uses PSApi.pas }</font></i>

    <pre>

    <i><font color=blue>// Hilfstyp für einen Zeiger auf ein Array aus Doppelworten</font></i>
    <b>type</b>
    PDWordArray = ^TDWordArray;
    TDWordArray = <b>array</b> [0..0] <b>of</b> DWord;

    </pre>
    <pre>

    <i><font color=blue>// Funktion liefert unter NT/2000 ein Array aller Prozeß-IDs
    // Rückgabewert ist die Anzahl der Prozeß-IDs</font></i>
    <b>function</b> NtGetProcesses(<b>out</b> PIdList: PDWordArray): DWord;
    <b>const</b>
    ENUM_PROCESSES_BLOCK = 1024;
    <b>var</b>
    cb: DWord;
    cbNeeded: DWord;
    <b>begin</b>
    Result := 0;
    PIdList := <b>nil</b>;
    cb := ENUM_PROCESSES_BLOCK * SizeOf(DWord);
    <b>try</b>
    <b>repeat</b>
    Inc(cb, ENUM_PROCESSES_BLOCK * SizeOf(DWord));
    ReallocMem(PIdList, cb);
    FillChar(PIdList^, cb, 0);
    cbNeeded := 0;
    EnumProcesses(PDWord(PIdList), cb, cbNeeded);
    <b>until</b> cbNeeded < (cb * 90 div 100);
    Result := cbNeeded <b>div</b> SizeOf(DWord);
    <b>finally</b>
    <b>if</b> Result = 0 <b>then</b>
    <b>begin</b>
    FreeMem(PIdList);
    PIdList := <b>nil</b>;
    <b>end</b>;
    <b>end</b>;
    <b>end</b>;

    </pre>
    <pre>

    <i><font color=blue>// Funktion gibt das Array aus Prozeß-IDs wieder frei</font></i>
    <b>procedure</b> NtFreeProcesses(<b>var</b> PIdList: PDWordArray);
    <b>begin</b>
    <b>if</b> Assigned(PIdList) <b>then</b>
    FreeMem(PIdList);
    PIdList := <b>nil</b>;
    <b>end</b>;

    </pre>
    <pre>

    <i><font color=blue>// Beispiel für die Suche nach einer Instanz von NotePad.exe
    // (Hinweis es werden alle gefunden.)</font></i>
    <b>procedure</b> TForm1.Button1Click(Sender: TObject);
    <b>var</b>
    Count: DWord;
    IDList: PDWordArray;
    Loop: DWord;
    Process: THandle;
    Module: HModule;
    cbNeeded: DWord;
    BaseName: <b>array</b> [0..MAX_PATH] <b>of</b> Char;
    <b>begin</b>
    <i><font color=blue>// Liste von Prozeß-IDs holen</font></i>
    Count := NtGetProcesses(IDList);
    <b>if</b> Assigned(IDList) <b>then</b>
    <b>try</b>
    <i><font color=blue>// Alle IDs durchlaufen</font></i>
    <b>for</b> Loop := 0 <b>to</b> Count - 1 <b>do</b>
    <b>begin</b>
    <i><font color=blue>// Prozeß zur Abfrage öffnen</font></i>
    Process := OpenProcess(PROCESS_QUERY_INFORMATION <b>or</b> PROCESS_VM_READ,
    False, IDList^[Loop]);
    <b>if</b> Process <> 0 <b>then</b>
    <b>try</b>
    <i><font color=blue>// Das erste Modul-Handle aus der Modul-Liste des Prozesses holen
    // (Wir brauchen nur das erste, da das Modul, mit dem der Prozeß
    // erzeugt wurde, immer das erste Modul in der Liste ist)</font></i>
    cbNeeded := 0;
    EnumProcessModules(Process, @Module, SizeOf(HModule), cbNeeded);
    <i><font color=blue>// Prüfen, ob das Modul-Handle gefüllt wurde</font></i>
    <b>if</b> cbNeeded >= SizeOf(HModule) <b>then</b>
    <b>begin</b>
    <i><font color=blue>// Basis des Dateinamen holen (ohne Pfad)</font></i>
    FillChar(BaseName, SizeOf(BaseName), 0);
    GetModuleBaseName(Process, 0, PChar(@BaseName[0]), SizeOf(BaseName));
    <i><font color=blue>// Der gesuchte Prozeß ???</font></i>
    <b>if</b> UpperCase(BaseName) = 'NOTEPAD.EXE' <b>then</b>
    ShowMessage('Eine Instanz der NotePad.exe wurde gefunden!'#13#10 +
    'Sie hat die Prozeß-ID: ' + IntToStr(IDList^[Loop]));
    <b>end</b>;
    <b>finally</b>
    <i><font color=blue>// Prozeß-Handle wieder schließen</font></i>
    CloseHandle(Process);
    <b>end</b>;
    <b>end</b>;
    <b>finally</b>
    <i><font color=blue>// Liste mit Prozeß-IDs wieder freigeben</font></i>
    NtFreeProcesses(IDList);
    <b>end</b>;
    <b>end</b>;

    </pre>

    Kommentar folgt in ca. 10 Minuten...
    &#10

    Comment


    • #3
      Unter Windows NT/2000 bekommt man mittels der PSApi-Funktion <b>EnumProcesses</b> eine Liste aller Prozeß-IDs. Das Problem an dieser Funktion ist, das sie uns nicht mitteilt, wieviele IDs denn vorhanden sind, also wie groß der Puffer sein muß. Deswegen habe ich eine eigene Funktion dafür geschrieben, die diesen Umstand berücksichtigt - und sicher wird die Funktion öfter benötigt.
      Damit die Programmierung unabhängig erfolgen kann, gibt es auch eine passende Funktion zum Freigeben des Puffers (Woher soll der Benutzer der Funktion wissen, ob GlobalFree, FreeMem, etc benutzt werden muß)
      <p>
      Mittels der Prozeß ID wird nun jeder Prozeß mit <b>OpenProcess</b> geöffnet. (PROCESS_VM_READ wird für die PSApi-Funktion benötigt, da diese Dateinamen direkt aus dem anderen Prozeßraum ausliest )
      <p>
      Nun holen wir uns das erste Modul-Handle aus dem Prozeß mit der PSApi-Funktion <b>EnumProcessModules</b>. Es wird nur das erste Modul benötigt, da dies dasjenige ist, mit dem der Prozeß erzeugt wurde.
      <p>
      Nun können wir mit dem Handle des Prozesses und dem Handle des ersten Moduls den Dateinamen des Moduls holen (hier nur ohne Pfad - <b>GetModulBaseName</b>, <b>GetModulFileNameEx</b> wäre für den ganzen Dateinamen mit Pfad) und überprüfen, ob es der gesuchte Prozeß ist...
      <p>
      Letzendlich werden alle angeforderten Handles und Speicher-Blöcke wieder freigegeben.
      <p>
      Gruß Nic

      Comment


      • #4
        Hallo Nico

        Besten Dank für Deine umfangreiche Hilfe.

        Gruss Stefa

        Comment

        Working...
        X