Internet Explorer se bloque lorsque MSXML2 :: IXMLDOMDocumentPtr - > Release () s'appelle

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

  •  22-07-2019
  •  | 
  •  

Question

Je crée une extension de shell en C ++ (ATL 9) à l'aide de Visual Studio 2008. L'extension de shell crée un objet global MSXML2 :: IXMLDOMDocumentPtr m_XmlDoc dans la classe de module. Ce m_XmlDoc est ensuite utilisé dans l’extension par toutes les classes pour lire le document XML.

Le problème auquel je suis confronté est Internet Explorer. Lorsque l'extension Shell est active et que j'ouvre / ferme Internet Explorer, j'obtiens un dialogue de débogage et IE se bloque. Le message d'erreur indique "Exception non gérée à l'adresse 0x6aac30f1 dans iexplore.exe: 0xC0000005: emplacement de lecture de la violation d'accès 0x03050970." Lorsque je clique sur "pause". dans la fenêtre de message, cela me mène à la "libération". méthode de COM Smart Pointer et l'erreur semble être sur m_pInterface- > Release ();

Cet appel a été effectué à partir du destructeur de Module et la valeur de m_pInterface n'est pas NULL. Je pense que peut-être qu'Internet Explorer utilise le DOM XML et que l'appel à Release crée un problème.

MSXML2::IXMLDOMDocumentPtr m_XmlDoc;

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

Code principalDll:

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); 
}
Était-ce utile?

La solution 3

Le problème était dû au pointeur intelligent COM utilisé pour XmlDomDocument. Je l'ai changé pour un pointeur normal et cela fonctionne bien, même sous Vista.

Ce problème a un comportement différent sous XP et Vista. Dans XP, je recevais une exception non gérée lorsque j'ai fermé Internet Explorer. Sous Vista, je n’étais pas en mesure de parcourir le lecteur virtuel.

Autres conseils

l'utilisation de DisableThreadLibraryCalls est découragée, vous l'avez vue?

Il y a au moins deux problèmes avec votre code tel que posté:

  1. Vous appelez CoInitialize dans DllMain.
  2. Vous créez un objet COM dans DllMain.
  3. Cela ne me surprendrait pas si vous faites quelque chose dans CreateImageLists () que vous ne devriez pas faire non plus dans DllMain.

En outre, la raison pour laquelle votre plantage a été "corrigé". en n'utilisant pas le pointeur intelligent, c'est parce que vous ne libérez plus réellement l'objet. Votre code est cassé et ne pas publier la référence n'est pas un moyen correct de réparer quoi que ce soit.

Je vous suggère de lire, puis de relire, la documentation de DllMain en accordant une attention particulière aux tâches à ne jamais effectuer lors de la mise en œuvre de la fonction. Comme vous le verrez tout de suite:

  

Avertissement Il existe de sérieuses limites à ce que vous pouvez faire dans un point d'entrée de DLL. Pour fournir une initialisation plus complexe, créez une routine d'initialisation pour la DLL. Vous pouvez demander aux applications d’appeler la routine d’initialisation avant d’appeler toute autre routine de la DLL.

Je pense qu'une fois que vous l'avez lu, corrigez le code pour créer l'objet COM à une heure valide et que vous le relâchez à une heure valide, l'extension de votre shell cesse de planter.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top