2012-04-13 6 views
7

Ich verwende den folgenden C# -Code in einem Windows-Dienst (der als NT_AUTHORITY\SYSTEM ausgeführt wird) zum Erstellen eines Ereignishandlers zum Empfangen von Prozesserstellungsereignissen (mithilfe von WMI und WQL):Prozessstart-Ereignis mit WMI - nicht alle Prozesse werden erkannt

string queryString = "SELECT * FROM Win32_ProcessStartTrace"; 
ManagementEventWatcher watcher = new ManagementEventWatcher(new WqlEventQuery(queryString)); 
watcher.EventArrived += new EventArrivedEventHandler(ProcessStartEvent); 
watcher.Start(); 

In ProcessStartEvent:

int processId = int.Parse(e.NewEvent.Properties["ProcessId"].Value.ToString()); 
Process proc = Process.GetProcessById(processId); 

Out("Received process: " + proc.ProcessName); 

Das Problem, das ich habe, ist, dass (aus unerfindlichen Gründen) nicht jeder Prozessstart ist c aptured und vom Programm gemeldet. Wenn ich ungefähr 6 Prozesse gleichzeitig starte, kann man nicht in der Ausgabe erscheinen.

Ich habe versucht, einige Untersuchungen zur Erfassung von Prozesserzeugungsereignissen mithilfe von WMI durchzuführen, aber es sind nur wenige Informationen verfügbar. Ich habe gesehen, dass es auch möglich ist, Verfahren zu erfassen beginnt etwas mit ähnlich ist:

SELECT TargetInstance 
FROM __InstanceCreationEvent 
WITHIN 2 
WHERE TargetInstance ISA 'Win32_Process' 

Gibt es zwischen der Verwendung von __InstanceCreationEvent und Win32_ProcessStartTrace keine großen Unterschiede (Wie in this Stack Overflow answer gesehen)? Könnte das der Grund für meine Probleme sein?

Gibt es eine Erklärung dafür, warum ich nicht empfangen Ereignisse für alle Prozess beginnt? Gibt es etwas Offensichtliches, dass ich hier falsch liege?

+0

Mögliche Duplikate von [.NET-Ereignisse für den ausführbaren Prozess von Process] (http://StackOverflow.com/Questions/848618/net-Events-for-Process-Executable-Start) –

+0

@Dimi Ich würde sagen, das ist ein ziemlich andere Frage, da sich hierauf konzentriert, warum einige Ereignisse scheinbar verschwinden, während andere sogar bei Verwendung der vermeintlich "korrekten" Methode zum Auffangen von Prozessstartereignissen gefangen werden. – Xenon

Antwort

6

Beide Methoden sind gültig, funktionieren aber auf verschiedene Arten. Wenn Sie die __InstanceCreationEvent WMI-Klasse verwenden, verwenden Sie ein intrinsic-Ereignis. Dies bedeutet, dass Sie Änderungen im Standard-WMI-Datenmodell überwachen (dies funktioniert wie ein Trigger in einer Tabelle).

Wenn Sie Win32_ProcessStartTrace verwenden, verwenden Sie ein Extrinsic-Ereignis. Dies bedeutet, dass Sie eine spezielle Ereignisklasse verwenden, die für eine bestimmte Aufgabe erstellt wurde. Überwachen Sie in diesem Fall die Erstellung des Prozesses.

Jetzt zurück zu Ihrem Problem, der beste Weg, um das "Verlorengehen" einiger Ereignisse zu vermeiden, ist ein permanent event consumer erstellen.

+0

Kann mit C# /. NET ein permanenter Ereignis-Consumer erstellt werden? – Xenon

+0

der Standard verwendet MOF, überprüfen Sie diesen Artikel [Erstellen von WMI-Abonnements für permanente Ereignisse mit MOF] (http: //www.codeproject.com/Articles/28226/Creating-WMI-Permanent-Event-Abonnements-Using-M) – RRUZ

+0

Das Problem mit der Verwendung von MOF ist, dass ich in der Lage sein muss, die Ereignisse in meiner C# Service-App zu erhalten. – Xenon

3

Ich habe gefunden, wenn Sie ein Ereignis erhalten, dass ein Prozess gestartet wurde - übergeben Sie das Ereignis in einen separaten Thread mit zum Beispiel Boost-Thread können Sie die Prozess-ID an einen neuen Thread übergeben.

Dies bedeutet, dass die WMI COM nicht in ein Gewirr gerät und sich selbst nicht mehr funktioniert.

siehe http://sourceforge.net/p/processhistory/code/HEAD/tree/trunk/PHLogger/COM_WMI_Consumer/

für einige Arbeits C++ Code.

Verwandte Themen