2009-07-21 8 views
3

Ich versuche, eine Anwendung zu erstellen, die mehrere Remotecomputer über WMI überwachen kann. Als C# -Entwickler habe ich den Namespace System.Management gewählt.System.Management.ManagementEventWatcher - Wiederherstellen von Verbindung

Aus Gründen der Leistung und Skalierbarkeit würde ich lieber eine ereignisgesteuerte Methode zum Erfassen von Informationen verwenden als eine Abfrage. Daher habe ich die ManagementEventWatcher-Klasse untersucht.

Für einfache Überwachungsaufgaben scheint diese Klasse genau das zu sein, was ich möchte. Ich erstelle das Objekt, gebe ihm Parameter ManagementScope, EventQuery und EventWatcherOptions, abonniere das Ereignis EventArrived und rufe die Methode Start auf (vereinfachtes Beispiel unten).

using SM = System.Management; 

    ... 

    SM.ManagementEventWatcher _watcher; 
    SM.ConnectionOptions   conxOptions; 
    SM.ManagementScope   scope; 
    SM.WqlEventQuery    eventQuery; 
    SM.EventWatcherOptions  eventOptions; 
    SM.EventArrivedEventHandler handler; 

    string path = @"\\machine\root\cimv2"; 

    conxOptions = new SM.ConnectionOptions(); 
    conxOptions.Username = user; 
    conxOptions.Password = password; 
    scope = new SM.ManagementScope (path, conxOptions); 
    scope.Connect(); 

    eventQuery = new SM.WqlEventQuery ("SELECT * FROM __InstanceCreationEvent WITHIN 10 WHERE TargetInstance ISA 'Win32_Process'"); 

    eventOptions = new SM.EventWatcherOptions(); 
    eventOptions.Context.Add ("QueryName", "Process Query"); 

    _watcher = new SM.ManagementEventWatcher (scope, eventQuery, eventOptions); 
    handler = new SM.EventArrivedEventHandler (HandleWMIEvent); 
    _watcher.EventArrived += handler; 
    _watcher.Start(); 

    Console.WriteLine ("Press Any Key To Continue"); 
    Console.ReadKey(); 

    _watcher.Stop(); 
    _watcher.EventArrived -= handler; 

Das Problem, das ich in laufen lasse, ist, dass es schwierig ist, zu erkennen, wenn die Verbindung zum Remote-Rechner hat durch verschiedene Mittel (Maschinen Neustart abgestürzten Router, unplugged Netzwerkkabel, etc.) gebrochen.

Die ManagementEventWatcher-Klasse scheint keine Möglichkeit zu bieten, festzustellen, dass die Verbindung unterbrochen wurde, da das Ereignis Stopped in diesem Fall nicht ausgelöst wird. Das ManagementScope-Objekt, das an den ManagementEventWatcher angeschlossen ist, zeigt weiterhin IsConnected als wahr an, obwohl die Verknüpfung unterbrochen ist.

Hat jemand irgendwelche Ideen, wie man den Verbindungsstatus überprüft?

Das einzige, was ich zu diesem Zeitpunkt denken kann, ist die Verwendung des ManagementScope-Objekts, um regelmäßig eine WMI-Abfrage für die Maschine durchzuführen und sicherzustellen, dass dies funktioniert, obwohl das nur die lokale-> Remote-Verbindung überprüfen kann die entsprechende remote-> lokale Verbindung. Ich nehme an, ich könnte eine andere WMI-Abfrage nachschlagen, die ich verwenden könnte, um die Verbindung zu überprüfen (vorausgesetzt, die Abfrage funktioniert), aber das scheint mehr Arbeit zu sein, als ich tun sollte.

Antwort

0

So weit ich sagen kann, wenn so etwas passiert, sollten Sie eine Ausnahme vom Typ ManagementException, die WbemErrCallCancelled WMI-Fehlercode (0x80041032) enthält, erhalten.

+1

Ich habe festgestellt, dass das ManagementEventWatcher.Stopped Ereignis ausgelöst wird, wenn der WMI-Dienst auf dem Remote-Computer neu gestartet wird, aber jedes andere Szenario (z. B. Neustart, Netzwerktrennung usw.), und ich nichts bekommen. In der Zwischenzeit habe ich nach einer Veranstaltung gesucht, um eine Art Herzschlag zu bieten, auf den ich mich verlassen kann. Für jede WindowsXP-Maschine und später kann ich "SELECT * FROM __InstanceModificationEvent WHERE TargetInstance ISA 'Win32_UTCTime' AND (TargetInstance.Seconds = 0 OR TargetInstance.Seconds = 30)" verwenden, um einen 30-Sekunden-Heartbeat bereitzustellen. Das muss letzten Endes meine Antwort sein, fürchte ich. –

1

Schauen Sie sich diesen Beitrag here. Sie erfahren, wie Sie feststellen können, wenn ein Wechseldatenträger mit C# eingelegt wird. Sie sollten mit Ihrem von Ihnen bereitgestellten WMI-Code verknüpft sein.

2

Es gibt zwei Arten von Ereigniskonsumenten in WMI - temporär und permanent. Was Sie vielleicht suchen, ist ein permanentes Event-Abonnement. Hier ist ein kurzer Klappentext darüber auf MSDN

Ein permanenter Consumer ist ein COM-Objekt, das jederzeit ein WMI-Ereignis empfangen kann. Ein permanenter Ereigniskonsument verwendet eine Reihe persistenter Objekte und Filter, um ein WMI-Ereignis zu erfassen. Wie bei einem temporären Ereigniskonsumenten richten Sie eine Reihe von WMI-Objekten und -Filtern ein, die ein WMI-Ereignis erfassen. Wenn ein Ereignis auftritt, das einem Filter entspricht, lädt WMI den permanenten Ereigniskonsumenten und benachrichtigt ihn über das Ereignis. Da ein permanenter Consumer im WMI-Repository implementiert ist und eine ausführbare Datei ist, die in WMI registriert ist, verarbeitet und empfängt der permanente Ereigniscustomer Ereignisse nach seiner Erstellung und sogar nach einem Neustart des Betriebssystems, solange WMI ausgeführt wird. Weitere Informationen finden Sie unter Ereignisse immer empfangen.

Dieser MSDN-Artikel sollte genug sein, um Sie in Fahrt zu bringen http://msdn.microsoft.com/en-us/library/aa393014(VS.85).aspx.

In meiner Situation im Umgang mit diesem Problem haben wir uns jedoch entschieden, die Daten abzufragen, anstatt einen permanenten Verbraucher zu erstellen. Eine andere Möglichkeit besteht darin, bestimmte Ereignisse (z. B. einen Neustart) zu überwachen und dann Ihren temporären Ereigniskonsumenten erneut zu registrieren.

1

Abonnieren Sie das Ereignis NetworkAvailabilityChange, damit Sie über die Eigenschaft NetworkAvailabilityEventArgs.IsAvailable über den Status Ihrer aktuellen Verbindung informiert werden. Mit ein wenig mehr Arbeit wird das Ereignis NetworkAddressChange Sie über Maschinen informieren, die sich bewegen, Adressen und usw. in Ihrem Netzwerk ändern. . . Die System.Net.NetworkInformation hat gute Informationen. . . Ich gehe davon aus, dass es Ihnen nichts ausmacht, etwas anderes als WMI zu verwenden, um dies zu überwachen.

Verwandte Themen