在什么情况下Internet Explorer无法正确卸载ActiveX控件?

时间:2008-09-15 17:54:53

标签: c++ internet-explorer internet-explorer-6 activex atl

我正在使用我正在编写的ActiveX控件遇到一个令人困惑的问题 - 有时,Internet Explorer似乎无法在进程关闭时正确卸载控件。这导致控件实例的析构函数未被调用。

控件是用C ++编写的,使用ATL并使用Visual Studio 2005进行编译。当用户浏览控件所嵌入的页面时,总是调用控件实例的析构函数 - 问题只发生在浏览器关闭时。

当我在调试器下运行IE时,我没有看到任何异常 - 调试器没有捕获任何异常,访问冲突或断言失败,但问题仍然存在 - 我可以在控件的析构函数中设置断点当我关闭broswer时,它永远不会被击中。

此外,当我加载一个嵌入控件的多个实例的简单HTML页面时,我没有看到问题。只有在我们的Web应用程序实例化控件时才会出现问题,该应用程序将标签动态插入到网页中 - 当然,不知道导致此问题的原因,我不知道这些信息是否相关,但它似乎表明这可能是一个IE问题,因为它依赖于数据。

当我在调试器下运行简单的测试用例时,我可以在控件的析构函数中设置一个断点,每次都会命中它。我相信这排除了控件本身的问题(比如,一个错误会阻止析构函数被调用,就像接口泄漏一样。)

我使用IE 6进行了大部分测试,但我也看到了IE 7上出现的问题。我还没有测试IE 8。

我现在的工作假设是动态HTML代码中有一些东西会导致浏览器泄漏ActiveX控件上的界面。到目前为止,我还没有能够生成一个很好的测试用例,可以在应用程序之外再现这个,并且应用程序有点太大而无法构建一个好的测试用例。

我希望有人能够深入了解可能导致此类行为的IE错误。顺便说一下,下面提供的答案太笼统了 - 我正在寻找一组特定的情况,这些情况已知会引起这种情况。当然有人在那里见过这个。

3 个答案:

答案 0 :(得分:3)

要使用C ++调试COM中的问题,其中没有调用对象的(C ++)析构函数,最好的方法是关注COM对象的refcounts如何递增或递减。可能发生的事情是有人将refcount增加了太多次,然后没有减少相同的次数。这导致对象没有被释放。

您的动态HTML可能只是在IE中显示错误,如果您使用静态页面,则不会发生此错误。

如果IE中存在错误,那么诀窍就是找出导致错误出现的原因,以及你可以做些什么来诱骗IE正确发布你的COM对象(比如,让HTML消失)。< / p>

答案 1 :(得分:0)

另一种方法 - 将清理代码添加到DllMain函数中(如果该函数尚不存在,则添加该函数)。然后,无论引用计数(和引用计数错误)如何,卸载DLL时都可以清理自己:

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

哦,还有一句警告 - 不要花太多时间进行清理 - 如果你这样做,我不能保证过程关闭也不会杀了你。

答案 2 :(得分:0)

我遇到同样的问题,但只能在特定的计算机上使用。 此计算机还存在Flash ActiveX的问题,在关闭选项卡后仍然存在。 我的猜测是问题不在你的代码中。你在其他电脑上遇到过这个问题吗?