2010-02-23 8 views
6

Ich verwende C# System.Diagnostic.Process Objekt.
Eine seiner Eigenschaften ist Id.
Die Id dies erzeugt ist nicht das gleiche wie die PID, in Windows Task Manager gezeigt.
Warum ist das?System.Diaganostics.Process.Id ist nicht die gleiche Prozess-ID, die im Task-Manager angezeigt wird. Warum?

Sie sehen, sobald dieser Prozess gestartet wird.
Es führt zwei andere nicht verwaltete Prozesse aus, für die ich keine expliziten IDs für Objektreferenzreferenzen erhalten kann.
Ich muss alle Prozesse durchsuchen, um sie nach Prozessname über System.Diagnostics.Process.GetProcesses() zu finden.

Ich versuche eine zuverlässige Möglichkeit zu finden, diesen Prozess und alle damit verbundenen Prozesse von PID, die in Task Manager zeigt.
Gibt es einen besseren Weg?

Ich kann nicht einfach alle Prozesse mit den zugehörigen Prozessnamen beenden, weil das andere Instanzen der Prozesse, die nichts mit meinem Programm zu tun haben, töten kann.

+2

Wenn Sie den Prozess mit System.Diagnostics.Process starten, dann rufen .Refresh() vor der ID-Überprüfung. Die ID wird vom Betriebssystem beim Start des Prozesses zugewiesen, nicht wenn das Process-Objekt instanziiert wird. –

Antwort

13

Der Schlüssel ist, dass Sie Ihren Prozess nicht durch Id töten möchten. In der Tat, das ist eine Race-Bedingung: Ihr erzeugter Prozess könnte sterben und ein anderer Prozess könnte mit der gleichen ID erstellt werden. Dann, wenn Sie gehen, um es zu töten, würden Sie am Ende den neuen Prozess anstelle des alten sterben, der bereits tot war.

Die zuverlässigste Methode, um erzeugte Prozesse zu beenden, besteht darin, sie in ein Job-Objekt einzufügen und den Job zu beenden, sobald Ihre Aufgabe abgeschlossen ist.

Hier ist ein einfacher Code ein Job-Klasse zu implementieren:

class Job 
{ 
    [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] 
    public static extern IntPtr CreateJobObject(IntPtr lpJobAttributes, string lpName); 

    [DllImport("kernel32.dll")] 
    public static extern bool AssignProcessToJobObject(IntPtr hJob, IntPtr hProcess); 

    [DllImport("kernel32.dll")] 
    public static extern bool TerminateJobObject(IntPtr hJob, uint uExitCode); 

    IntPtr job; 

    public Process StartProc(string commandLine) 
    { 
     if (job == IntPtr.Zero) 
      job = CreateJobObject(IntPtr.Zero, null); 
     ProcessStartInfo si = new ProcessStartInfo(@"c:\windows\system32\cmd.exe"); 
     si.Arguments = "/c " + commandLine; 
     si.CreateNoWindow = false; 
     si.UseShellExecute = false; 
     Process proc = Process.Start(si); 
     AssignProcessToJobObject(job, proc.Handle); 
     return proc; 
    } 

    public void TerminateProc() 
    { 
     // terminate the Job object, which kills all processes within it 
     if (job != null) 
      TerminateJobObject(job, 0); 
     job = IntPtr.Zero; 
    } 
} 
+0

Ich stellte mir diese Möglichkeit vor, wusste aber nicht, was ich tun sollte. Werden diese Unmanage-Sub-Prozesse (die indirekt durch den von mir gestarteten Prozess gestartet werden) auch diesem Job-Objekt untergeordnet zugeordnet? Also, wenn ich den Job töte, werden alle 3 Prozesse getötet? –

+0

BTW, ich habe Angst vor Code in spitzen Klammern; Ich verstehe es noch nicht. Sind diese Attribute an der Spitze? Ist dieser Code auf 32-Bit-Architektur beschränkt? –

+1

Das Beenden des Job-Objekts beendet den Prozess, den Sie gestartet haben, und alle damit begonnenen Prozesse und so weiter. Und ja, das sind Attribute in Klammern. Ich habe das nicht auf einer 64-Bit-Maschine ausgeführt, aber es gibt keinen Grund zu glauben, dass es nicht funktioniert. – Gabe

1

Ich kann das nicht reproduzieren. Ich habe gerade den folgenden Code ausgeführt:

Alle aufgelisteten Prozesse entsprechen der PID im Task-Manager. Dies ist mit Windows 7 - welches Betriebssystem verwenden Sie? Wenn Sie sich andere Prozesse ansehen, tun Sie sie übereinstimmen mit der PID im Task-Manager angezeigt?

+0

Jon, die anderen beiden Prozesse (die nicht verwalteten beginnen indirekt durch den Prozess, den ich starte) stimmen überein. Aber die ID des Prozesses, die ich starte, unterscheidet sich im Task-Manager von der Property-Referenz über myProcess.Id. –

+0

BTW, mag ich .OrderBy Methode, die Sie gebucht haben. Ich wusste nicht, dass du das tun kannst. –

Verwandte Themen