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

Posted

技术标签:

【中文标题】Internet Explorer 在啥情况下无法正确卸载 ActiveX 控件?【英文标题】:Under what circumstances does Internet Explorer fail to properly unload an ActiveX control?Internet Explorer 在什么情况下无法正确卸载 ActiveX 控件? 【发布时间】:2010-09-09 01:43:06 【问题描述】:

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

该控件是用 C++ 编写的,使用 ATL 并使用 Visual Studio 2005 编译。当用户浏览远离嵌入控件的页面时,始终调用控件实例的析构函数 - 只有在关闭浏览器时才会出现问题.

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

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

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

我的大部分测试都是使用 IE 6 进行的,但我发现问题也出现在 IE 7 上。我还没有测试过 IE 8。

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

我希望有人能够深入了解可能导致这种行为的 IE 错误。顺便说一句,下面提供的答案太笼统了——我正在寻找一组已知会导致这种情况的特定情况。肯定有人以前见过这个。

【问题讨论】:

【参考方案1】:

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

您的动态 HTML 可能只是在 IE 中显示了一个错误,而如果您使用静态页面则不会发生这种情况。

如果 IE 中存在错误,诀窍是找出导致错误出现的原因,以及您可以采取哪些措施来诱使 IE 正确释放您的 COM 对象(例如,使 HTML 消失)。

【讨论】:

感谢您的建议。动态 HTML 代码非常复杂,以至于没有人完全确定它是如何工作的,而我试图解开它以创建一个重现问题的测试用例的尝试到目前为止都失败了。【参考方案2】:

另一种方法 - 将清理代码添加到您的 DllMain 函数(如果该函数不存在,则添加该函数)。然后不管引用计数(和引用计数错误),当你的 DLL 被卸载时,你可以清理自己:

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

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

【讨论】:

您确实意识到在用 MFC 编写的控件中无法做到这一点,对吧? 为什么?我不是 MFC 专家,但我看不出像 MFC 这样的库如何阻止您提供自己的 DllMain(如果您想包含一个)。您的意思是 MFC 控件不提供清理它们的方法吗?如果是这样的话,令人惊讶。 或者您的意思是 MFC 提供了自己的 DllMain 实现,并且不允许您挂钩?那会是个问题。 这是问题的一部分。另一部分是 MFC 控件的确切清理顺序由 MFC 控制,您最好远离它——尤其是在确实发生了清理但并非总是如此的情况下。 ATL 类似,但我对细节的熟悉程度不如 MFC。 好的,那么我的 MFC 无知就暴露出来了。如果 MFC 有特殊的清理要求,我对此了解的不够多,无法提供帮助。【参考方案3】:

我有同样的问题,但只是在特定的计算机上。 这台计算机的 Flash ActiveX 也有问题,关闭选项卡后它仍然存在。 我的猜测是问题不在于您的代码。您在其他计算机上是否有此问题?

【讨论】:

我在其他机器上见过这个。

以上是关于Internet Explorer 在啥情况下无法正确卸载 ActiveX 控件?的主要内容,如果未能解决你的问题,请参考以下文章

windows mobile在没有regedit的情况下在internet explorer中隐藏sip(键盘)(仅限html,js)

对于某些情况,如 Internet Explorer 特定的 CSS 或 Internet Explorer 特定的 JavaScript 代码,如何仅针对 Internet Explorer 10?

无法在 Internet Explorer 8 中显示 SVG 图表

arcgis空间参考修改在啥情况下无法完成

如何使用 Internet Explorer 使 div 居中?

.InnerHTML 在 Internet Explorer 中无法正常工作