| 

.NET C# Java Javascript Exception

4
Hallo,

ich möchte gerne benachrichtigt werden, wenn eine Module in einem Prozess geladen wird.
Leider gibt es kein
Process.GetCurrentProcess().ModuleLoaded oder
Process.GetCurrentProcess().Modules.Added

AssemblyLoaded an der AppDomain reicht mir nicht, da ich auch Dll´s mitbekommen möchte, die nicht .net Dll´s sind.
11.07.2011
Gast
41 2
6 Antworten
4
Ja, das trifft den Kern meines Problems besser.
Es geht nicht um´s Überwachen sondern um das schnelle Herausfinden des Verursachers.
Generell habe ich auch keine Probleme die Verursacher zu finden (statische zur Compile-Zeit, Debugging usw. ).
Es geht mir nur um das schnelle und einfache Herausfinden ohne das System in seiner Gesamtheit untersuchen zu müssen.

Z.B. um zu Prüfen ob eine spezielle DLL in diesem Umfeld wirklich gebraucht wird.
Evtl. wird sie ja erst später gebraucht und man könnte sie erst "on demand" laden (Performance-Aspekt, Speicher u. Laufzeit).

Es gibt komplexe Abhängigkeiten inkl. Legacy- oder Fremdanbieter-Dlls die man nicht statisch zur Compile-Zeit prüfen kann.
Manchmal reicht auch schon ein unüberlegtes "using".
Z.B. ändert sich eine Zulieferer-Komponente und dort in der zehnten Dll-Abhängigkeitskette wird jetzt plötzlich eine "alte" Dll angezogen die ich nicht im Prozessraum haben möchte.

Noch ein Beispiel: Wer zieht WPF-Assemblies an obwohl es sich eigentlich um eine WinForms-Anwendung handelt. Oder braucht man diese Dll´s doch? -> Schnelles Herausfinden des Verursachers.
Soetwas bekomme ich aber mit dem AssemblyLoaded-Event raus.

Gruß

CodeSniffer
12.07.2011
CodeSniffer 1,3k 4 9
3
Ich hab jetzt mal ne Zeit lang recherchiert und einige Sachen ausprobiert, finde aber weder brauchbare Win32 API Calls, noch ne adäquate Möglichkeit, es mit WMI umzusetzen. Mit WMI kann man zwar ne EventQuery für einen __InstanceModificationEvent aufsetzen, etwa so

watcher = new ManagementEventWatcher(@"root\cimv2", "SELECT * FROM __InstanceModificationEvent WITHIN 1 WHERE TargetInstance ISA 'Win32_Process' AND TargetInstance.ProcessId = '" + Process.GetCurrentProcess().Id + "'");
watcher.EventArrived += (sender, evArgs) =>
{
Console.WriteLine(evArgs.NewEvent.ClassPath);
};
watcher.Start();


aber der feuert leider alle Sekunde (siehe WITHIN 1), auch ohne Änderung. Kann sein, dass ich da was falsch mache, vlt. kennt sich hier jemand mit WMI besser aus, der weiterhelfen kann.
EDIT
Hab eben noch überprüft: Es werden jede Sekunde (WITHIN 1) immer 4 Properties im Event als geändert notifziert, evtl. kann man da noch filtern?!? In der Query vielleicht? Wenn diese (eigentlich überflüssigen) Events rausgefiltert werden kpoönnten, könnte man mit

"associators of {win32_process.handle='" + Process.GetCurrentProcess().Id + "'} where AssocClass = CIM_ProcessExecutable"

im Callback versuchen, an die Module ranzukommen.
END EDIT

Nach alledem was ich bisher so gesehen habe, scheint mir ein separater Thread/Timer, der
Process.GetCurrentProcess().Modules
pollt und mit dem letzten Zustand vergleicht eine vergleichsweise einfache und schnelle Lösung zu sein, mit der man durchaus leben kann. Polling ist eigentlich nichts, was ich grundsätzlich empfehlen würde, aber ich hab in der letzten Stunde nichts Brauchbares gefunden, was mir in irgendeiner Weise einen Callback in diesem Fall liefert.

Das einzige, was wohl einen derartigen Callback unterstützt, scheint mir an sich eine sehr schwergewichtige und unhandliche Angelegenheit zu sein, kannst Du hier nachlesen:
MSDN Magazine: Examine Running Processes Using Both Managed and Unmanaged Code

Gruß
Florian
11.07.2011
ffordermaier 8,4k 3 9
2
Hallo Florian,

vielen Dank für die Recherchen.
Über einen separaten Thread und einem Polling-Mechanismus würde man schon an neu hinzugekommene Module herankommen.

Das ist aber nicht mein Ziel.
Mich interessiert der Verursacher. Die Code-Stelle die dafür verantwortlich ist, dass das Modul geladen wurde.

In einem großes Projekt mit vielen Mitarbeitern kommt es immer wieder dazu, dass DLL´s auf unterschiedliche Wege herangezogen und geladen werden, obwohl sie "eigentlich" nicht gebraucht werden.
Meine Idee war es den CallStack des Verursachers auszugeben.

Ein anderer Weg wäre die zu untersuchende Dll zu löschen und dann den CallStack der Exception zu untersuchen. Ein schönerer Weg wäre mir nur lieber gewesen.

Gruß

CodeSniffer
12.07.2011
CodeSniffer 1,3k 4 9
1
Wenn ich Dich also richtig verstehe, versuchst Du zur Laufzeit denjenigen zu identifzieren, der für das Laden eines bestimmten Moduls verantwortlich ist. Ich gehe davon aus, dass es sich dabei ausschließlich um dynamisch hinzugeladene Module handelt, denn alles andere kann bereits zur Compilezeit statisch geprüft werden (da sollte es adäquate Toolunterstützung für geben). Desweiteren sind Styleguides und Coding-Guidelines (wenn nicht bereits geschehen) dahingehend zu ergänzen, dass vor Abgabe auf derartig "überflüssiges Zeug" geprüft wird, defnierte Wege für das Laden von DLLs zu benutzen sind..., und als !verbindlich! zu postulieren. Bei einem großen System habt Ihr sicher auch eine Rolle "Build-/IntegrationManager" (o.ä.), der dann genau das dann auch beim Build noch einmal checken kann. Also eine Art toolgestützte prozesstechnische Herangehensweise.

Das schließt aber in meinen Augen aus, dass zur Laufzeit "eigentlich überflüssige" Module dynnamisch geladen werden, weil das wär ja völlig sinnfrei (nach dem Motto: bevor ich meinen Thread hier schlafen lass, weil er grad nix zu tun hat, zieh ich mal lieber n bisschen unnützes Zeugs an). Diese zur Laufzeit geladenen Module werden also tatsächlich gebraucht, was dann wiederum aber keine Laufzeitüberprüfung mehr benötigen sollte.

Trifft das den Kern Deines Problems besser? Wenn nicht, nenn bitte ein paar Beispiele, wie und wann Module "überflüssiger- und verbotenerweise" geladen werden, die Du gerne überwachen möchtest.

Gruß
Florian
12.07.2011
ffordermaier 8,4k 3 9
1
Das ist auf alle Fälle nicht trivial, was Du da beschreibst und vorhast. Eben habe ich noch etwas gefunden, was Dich evtl. weiterbringen könnte.
Das Ganze nennt sich ETW (Event Tracing for Windows), hab ich noch nie gehört von, aber scheint in die richtige Richtung zu laufen.
Im MSDN Magazine gibts nen Artikel über die Architektur und Basics.
Hier ist noch ein Blogeintrag, der mit .NET das Ganze schon irgendwie anzapft.
Using .NET 4.0 Event Tracing for Windows (ETW) along with application ETW
Habs nur überflogen, aber vielleicht hilfts weiter.

Gruß
Florian
12.07.2011
ffordermaier 8,4k 3 9
0
Danke für den Tipp. Werde ich mir bei Gelegenheit mal ansehen.
Das Ganze ist nicht so dringend, wäre ein recht nettes Feature um schnell zum Ziel zu kommen.

Gruß

CodeSniffer
12.07.2011
CodeSniffer 1,3k 4 9
Für sowas am Besten die Kommentarfunktion nutzen. Das spart Zeit und hält die Frage schön sauber :-)
Dustin Klein 12.07.2011
Wär nett, wenn Du Deine Erfahrungen bzw. Erkenntnisse bzgl. ETW rückmelden könntest, falls Du den Versuch wagst. Danke :-)
– Gast 12.07.2011
Sorry, war nicht eingeloggt :-(, vorheriger Kommentar is von mir...
ffordermaier 12.07.2011

Stelle deine .net-Frage jetzt!
TOP TECHNOLOGIES CONSULTING GmbH