Internet Explorer падает, когда вызывается MSXML2 :: IXMLDOMDocumentPtr -> Release () - PullRequest
0 голосов
/ 13 марта 2009

Я создаю расширение оболочки в C ++ (ATL 9) с использованием Visual Studio 2008. Расширение оболочки создает глобальный объект MSXML2 :: IXMLDOMDocumentPtr m_XmlDoc в классе модуля. Этот m_XmlDoc затем используется в расширении всеми классами для чтения XML-документа.

Проблема, с которой я сталкиваюсь, связана с Internet Explorer. Когда расширение Shell активно, и я открываю / закрываю Internet Explorer, я получаю диалог отладки, и IE вылетает. Сообщение об ошибке гласит: «Необработанное исключение в 0x6aac30f1 в iexplore.exe: 0xC0000005: Местоположение чтения нарушения доступа 0x03050970». Когда я нажимаю кнопку «разбить» в окне сообщения, я перехожу к методу «Отпустить» COM Smart Pointer, и кажется, что ошибка включена m_pInterface-> Release ();

Этот вызов был сделан из деструктора Модуля, а также значение m_pInterface не NULL. Я думаю, что, возможно, Internet Explorer использует XML DOM, и вызов Release создает в нем некоторую проблему.

MSXML2::IXMLDOMDocumentPtr m_XmlDoc;

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

Код dllMain:

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); 
}

Ответы [ 3 ]

0 голосов
/ 16 марта 2009

Проблема была из-за COM Smart Pointer, используемого для XmlDomDocument. Я изменил его на обычный указатель, и он отлично работает даже в Vista.

Эта проблема имеет другое поведение в XP и Vista. В XP я получал необработанное исключение, когда закрывал Internet Explorer. В Vista мне не удалось просмотреть виртуальный диск.

0 голосов
/ 20 марта 2009

Существует как минимум две проблемы с вашим кодом, как было опубликовано:

  1. Вы вызываете CoInitialize в DllMain.
  2. Вы создаете COM-объект в DllMain.
  3. Меня не удивит, если вы делаете что-то в CreateImageLists (), чего не следует делать и в DllMain.

Кроме того, причина того, что ваш сбой был «исправлен» из-за того, что вы не использовали умный указатель, заключается в том, что теперь вы больше не отпускаете объект. Ваш код не работает, и отказ от ссылки не является правильным способом исправить что-либо.

Я бы посоветовал вам прочитать, а затем перечитать документацию по DllMain , уделяя особое внимание вещам, которые вы никогда не должны делать в своей реализации функции. Как вы увидите прямо вперед:

Предупреждение Существуют серьезные ограничения на то, что вы можете делать в точке входа DLL. Чтобы обеспечить более сложную инициализацию, создайте процедуру инициализации для DLL. Вы можете требовать, чтобы приложения вызывали подпрограмму инициализации перед вызовом любых других подпрограмм в DLL.

Я подозреваю, что как только вы прочитаете его, исправите код для создания COM-объекта в правильное время и освободите его в правильное время, расширение вашей оболочки перестанет падать.

0 голосов
/ 15 марта 2009

использование DisableThreadLibraryCalls не рекомендуется, вы видели это?

...