Internet Explorer falha quando MSXML2 :: IXMLDOMDocumentPtr -> Release () é chamado

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

  •  22-07-2019
  •  | 
  •  

Pergunta

Estou criando uma extensão de shell em C ++ (ATL 9) usando o Visual Studio 2008. A Shell Extensão cria um m_XmlDoc mundial objeto MSXML2 :: IXMLDOMDocumentPtr na classe módulo. Este m_XmlDoc é então utilizado na extensão por todas as classes de ler documento XML.

O problema que estou enfrentando é com o Internet Explorer. Quando a extensão Shell está ativa e eu abrir / fechar o Internet Explorer, eu recebo uma caixa de diálogo de depuração e IE falha. A mensagem de erro diz "Exceção não tratada no 0x6aac30f1 em iexplore.exe: Violação de acesso local de leitura 0x03050970: 0xC0000005." Quando eu clicar em "pausa" na janela de mensagem, Leva-me para o método "Release" do COM ponteiro inteligente eo erro parece estar em m_pInterface-> Release ();

Esta chamada foi feita a partir de destruição do módulo e também o valor de m_pInterface não é NULL. Eu acho que talvez o Internet Explorer está usando o DOM XML ea chamada para lançamento cria algum problema nele.

MSXML2::IXMLDOMDocumentPtr m_XmlDoc;

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

código de 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); 
}
Foi útil?

Solução 3

O problema era por causa do COM ponteiro inteligente usado para XMLDOMDocument. Eu mudei para um ponteiro normal e ele está funcionando bem, mesmo em Vista.

Este problema tem um comportamento diferente no XP e Vista. No XP, eu estava ficando uma exceção não tratada quando fechei Internet Explorer. No Vista, eu não era capaz de navegar a unidade virtual.

Outras dicas

o uso de DisableThreadLibraryCalls está desanimado, você viu isso?

Há pelo menos dois problemas com seu código conforme publicado:

  1. Você está chamando CoInitialize no DllMain.
  2. Você está criando um objeto COM no DllMain.
  3. Não me surpreenderia se você está fazendo algo em CreateImageLists () que você também não deveria estar fazendo no DllMain.

Além disso, a razão que seu acidente foi "corrigido" por não usar o ponteiro inteligente é porque agora você não está realmente liberar o objeto mais. Seu código é quebrado, e não liberar a referência não é uma forma válida de corrigir alguma coisa.

Gostaria de sugerir que você lê, e, em seguida, voltar a ler, a documentação para DllMain com especial atenção para as coisas que você nunca deve fazer dentro da sua implementação da função. Como você verá frente até certo:

Aviso Há limites sérios sobre o que você pode fazer em um ponto de entrada DLL. Para fornecer a inicialização mais complexos, criar uma rotina de inicialização para a DLL. Você pode exigir aplicações para chamar a rotina de inicialização antes de chamar qualquer outras rotinas na DLL.

Eu suspeito que uma vez que você lê-lo, e corrigir o seu código para criar o objeto COM em um momento válido, e soltá-lo em um momento válido, sua extensão shell vai parar de bater.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top