Internet Explorer se bloquea cuando MSXML2 :: IXMLDOMDocumentPtr - > Release () se llama

StackOverflow https://stackoverflow.com/questions/641896

  •  22-07-2019
  •  | 
  •  

Pregunta

Estoy creando una extensión de shell en C ++ (ATL 9) usando Visual Studio 2008. La extensión de Shell crea un objeto global MSXML2 :: IXMLDOMDocumentPtr m_XmlDoc en la clase de módulo. Este m_XmlDoc se usa en la extensión por todas las clases para leer el documento xml.

El problema que estoy enfrentando es con Internet Explorer. Cuando la Extensión de Shell está activa y abro / cierro Internet Explorer, aparece un cuadro de diálogo de depuración y IE falla. El mensaje de error dice "Excepción no controlada en 0x6aac30f1 en iexplore.exe: 0xC0000005: Ubicación de lectura de infracción de acceso 0x03050970". Cuando hago clic en "romper" en la ventana del mensaje, me lleva a la " Liberación " método de puntero inteligente COM y el error parece estar activado m_pInterface- > Release ();

Esta llamada se realizó desde el destructor del Módulo y también el valor de m_pInterface no es NULL. Creo que tal vez Internet Explorer está utilizando el DOM XML y la llamada a Release crea algún problema en él.

MSXML2::IXMLDOMDocumentPtr m_XmlDoc;

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

dllCódigo principal:

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); 
}
¿Fue útil?

Solución 3

El problema se debió al puntero inteligente COM utilizado para XmlDomDocument. Lo cambié a un puntero normal y funciona bien incluso en Vista.

Este problema tiene un comportamiento diferente en XP y Vista. En XP, recibí una excepción no controlada cuando cerré Internet Explorer. En Vista, no pude navegar por la unidad virtual.

Otros consejos

se desaconseja el uso de DisableThreadLibraryCalls, ¿lo ha visto?

Hay al menos dos problemas con su código publicado:

  1. Estás llamando a CoInitialize en DllMain.
  2. Estás creando un objeto COM en DllMain.
  3. No me sorprendería si está haciendo algo en CreateImageLists () que tampoco debería estar haciendo en DllMain.

Además, la razón por la que su bloqueo fue " reparado " al no usar el puntero inteligente es porque ahora ya no estás soltando el objeto. Su código está roto y no liberar la referencia no es una forma válida de arreglar nada.

Le sugiero que lea y luego vuelva a leer la documentación de DllMain prestando especial atención a las cosas que nunca debe hacer dentro de su implementación de la función. Como verá al principio:

  

Advertencia Existen límites serios sobre lo que puede hacer en un punto de entrada de DLL. Para proporcionar una inicialización más compleja, cree una rutina de inicialización para la DLL. Puede requerir que las aplicaciones llamen a la rutina de inicialización antes de llamar a cualquier otra rutina en la DLL.

Sospecho que una vez que lo lea, y corrija su código para crear el objeto COM en un momento válido, y lo libere en un momento válido, su extensión de shell dejará de fallar.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top