-1

我正在使用 Visual Studio 2008 在 C++ (ATL 9) 中创建一个外壳扩展。外壳扩展在模块类中创建一个全局 MSXML2::IXMLDOMDocumentPtr 对象 m_XmlDoc。然后所有类在扩展中使用这个 m_XmlDoc 来读取 xml 文档。

我面临的问题是 Internet Explorer。当 Shell 扩展处于活动状态并且我打开/关闭 Internet Explorer 时,我得到一个调试对话框并且 IE 崩溃。错误消息显示“iexplore.exe 中 0x6aac30f1 处的未处理异常:0xC0000005:访问冲突读取位置 0x03050970。” 当我在消息窗口上单击“中断”时,它会将我带到 COM 智能指针的“释放”方法,错误似乎在 m_pInterface->Release();

此调用是从 Module 的析构函数进行的,并且 m_pInterface 的值也不为 NULL。我想也许 Internet Explorer 正在使用 XML DOM,并且对 Release 的调用会在其中产生一些问题。

MSXML2::IXMLDOMDocumentPtr m_XmlDoc;

In _AtlModule.Init() method
    ::CoInitialize(NULL);
    m_XmlDoc.CreateInstance(MSXML2::CLSID_DOMDocument40);

dll主要代码:

extern "C" BOOL WINAPI DllMain(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
{
    ::CoInitialize(NULL);
    if (dwReason == DLL_PROCESS_ATTACH)
    {
        _AtlModule.Init();  
        CreateImageLists();
        ::DisableThreadLibraryCalls(hInstance);
    }

    hInstance;
    return _AtlModule.DllMain(dwReason, lpReserved); 
}
4

3 回答 3

0

不鼓励使用 DisableThreadLibraryCalls,你看到了吗?

于 2009-03-15T01:03:00.977 回答
0

您发布的代码至少存在两个问题:

  1. 您在 DllMain 中调用 CoInitialize。
  2. 您正在 DllMain 中创建一个 COM 对象。
  3. 如果你在 CreateImageLists() 中做一些你也不应该在 DllMain 中做的事情,我不会感到惊讶。

此外,通过不使用智能指针来“修复”您的崩溃的原因是因为现在您实际上不再释放对象了。您的代码已损坏,并且不发布引用不是解决任何问题的有效方法。

我建议您阅读,然后重新阅读DllMain的文档,特别注意在函数实现中您不应该做的事情。正如您将在前面看到的:

警告 您可以在 DLL 入口点执行的操作受到严格限制。要提供更复杂的初始化,请为 DLL 创建一个初始化例程。您可以要求应用程序在调用 DLL 中的任何其他例程之前调用初始化例程。

我怀疑一旦你阅读它,并修复你的代码以在有效时间创建 COM 对象,并在有效时间释放它,你的 shell 扩展将停止崩溃。

于 2009-03-20T16:40:03.210 回答
-1

问题是因为用于 XmlDomDocument 的 COM 智能指针。我将其更改为普通指针,即使在 Vista 中也可以正常工作。

此问题在 XP 和 Vista 中具有不同的行为。在 XP 中,当我关闭 Internet Explorer 时,我遇到了一个未处理的异常。在 Vista 中,我无法浏览虚拟驱动器。

于 2009-03-16T06:11:56.060 回答