2008-09-15 5 views
1

Ich stoße auf ein verblüffendes Problem mit einem ActiveX-Steuerelement, das ich schreibe - manchmal scheint Internet Explorer das Steuerelement beim Herunterfahren des Prozesses nicht ordnungsgemäß zu entladen. Dies führt dazu, dass der Destruktor der Steuerinstanz nicht aufgerufen wird. Das Steuerelement wird in C++ geschrieben, verwendet ATL und wird mit Visual Studio 2005 kompiliert. Der Destruktor der Steuerinstanz wird immer aufgerufen, wenn der Benutzer von der Seite weggeht, in die das Steuerelement eingebettet ist. Das Problem tritt nur auf, wenn der Browser ausgeführt wird geschlossen.Unter welchen Umständen kann Internet Explorer ein ActiveX-Steuerelement nicht ordnungsgemäß entladen?

Wenn ich IE unter einem Debugger ausführen, sehe ich nichts ungewöhnliches - der Debugger fängt keine Ausnahmen, Zugriffsverletzungen oder Assertionsfehler, aber das Problem ist immer noch da - ich kann einen Haltepunkt im Steuerelement setzen Destruktor und es wird nie getroffen, wenn ich den Broswer schließe.

Darüber hinaus sehe ich das Problem nicht, wenn ich eine einfache HTML-Seite laden, die mehrere Instanzen des Steuerelements einbettet. Das Problem scheint nur dann zu passieren, wenn das Steuerelement von unserer Webanwendung instanziiert wird, die Tags dynamisch in die Webseite einfügt - natürlich weiß ich nicht, was dieses Problem verursacht, ich weiß nicht, ob dieses Informationsstück relevant ist oder nicht, aber es scheint darauf hinzuweisen, dass dies ein IE-Problem sein könnte, da es datenabhängig ist.

Wenn ich den einfachen Testfall unter dem Debugger ausführen, kann ich einen Haltepunkt im Destruktor des Steuerelements festlegen und es wird jedes Mal getroffen. Ich glaube, dass dies ein Problem mit dem Steuerelement selbst ausschließt (sagen wir, ein Fehler, der verhindern würde, dass der Destruktor jemals aufgerufen wird, wie ein Schnittstellenleck.)

Ich mache die meisten meiner Tests mit IE 6, aber ich habe Das Problem tritt auch bei IE 7 auf. Ich habe IE 8 nicht getestet.

Meine Arbeitshypothese ist jetzt, dass es etwas im dynamischen HTML-Code gibt, der verursacht, dass der Browser eine Schnittstelle auf dem ActiveX-Steuerelement verliert. Bisher war ich nicht in der Lage, einen guten Testfall zu erstellen, der dies außerhalb der Anwendung reproduziert, und die Anwendung ist ein bisschen zu groß, um einen guten Testfall zu erstellen.

Ich hatte gehofft, dass jemand in der Lage sein könnte, Einblick in mögliche IE Bugs zu geben, die bekanntermaßen diese Art von Verhalten verursachen. Die Antwort, die unten gegeben wird, ist übrigens zu allgemein - ich suche nach bestimmten Umständen, die dafür verantwortlich sind. Jemand hat das schon einmal gesehen.

Antwort

3

Um ein Problem in COM mit C++ zu debuggen, in dem der Destruktor eines Objekts (C++) nicht aufgerufen wird, ist der beste Ansatz, auf die Refcounts des COM-Objekts zu inkrementieren oder zu dekrementieren. Was wahrscheinlich geschieht, ist, dass jemand den Refcount zu oft erhöht und dann nicht mehr so ​​oft dekrementiert. Dies führt dazu, dass das Objekt nicht freigegeben wird.

Es ist möglich, dass Ihr dynamischer HTML-Code einfach einen Fehler im IE anzeigt, der bei Verwendung einer statischen Seite nicht auftritt.

Wenn es einen Fehler im IE gibt, wäre der Trick herauszufinden, was den Fehler verursacht und was Sie tun können, um IE dazu zu bringen, Ihr COM-Objekt korrekt freizugeben (wie HTML wegzulassen).

+0

Danke für die Vorschläge. Der dynamische HTML-Code ist so haarig, dass niemand genau weiß, wie er funktioniert, und meine Versuche, ihn so weit zu entwirren, dass ein Testfall entsteht, der das Problem reproduziert, sind bisher gescheitert. –

0

Ein anderer Ansatz - fügen Sie Cleanup-Code zu Ihrer DllMain-Funktion (Hinzufügen dieser Funktion, wenn es nicht bereits vorhanden ist).Dann unabhängig von Referenzzähler (und Referenz Zählfehler), wenn die DLL entladen ist, können Sie selbst aufzuräumen:

BOOL WINAPI DllMain(HINSTANCE, DWORD dwReason, LPVOID) { 
    if (dwReason == DLL_PROCESS_DETACH) { 
     CleanUpAnyObjectsStillAlive(); 
    } 
} 

Ach ja, und ein Wort der Warnung - nehmen Sie nicht zu lange Ihre Bereinigung tun - wenn Sie Ich kann nicht versprechen, dass das Herunterfahren des Prozesses dich sowieso nicht umbringt.

+0

Sie erkennen, dass in einem MFC-Steuerelement das nicht möglich ist, richtig? –

+0

Warum? Ich bin kein MFC-Experte, aber ich sehe nicht, wie eine Bibliothek wie MFC * verhindern kann, dass Sie Ihre eigene DllMain-Datei bereitstellen, wenn Sie eine hinzufügen möchten. Meinst du, dass MFC-Steuerelemente keine Möglichkeit bieten, sie zu bereinigen? Überraschend, wenn der Fall. – Bruce

+0

Oder meinst du vielleicht, MFC bietet eine eigene Implementierung von DllMain und erlaubt es Ihnen nicht, sich daran zu hängen? Das wäre ein Problem. – Bruce

0

Ich habe das gleiche Problem, aber nur auf einem bestimmten Computer. Dieser Computer hat auch ein Problem mit dem Flash ActiveX, das nach dem Schließen des Tabs aktiv bleibt. Meine Vermutung ist, dass das Problem nicht mit Ihrem Code ist. Haben Sie dieses Problem auf anderen Computern?

+0

Ich habe das auf anderen Maschinen gesehen. –

Verwandte Themen