يتعطل برنامج Internet Explorer عند استدعاء MSXML2::IXMLDOMDocumentPtr -> Release()

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

  •  22-07-2019
  •  | 
  •  

سؤال

أقوم بإنشاء ملحق Shell في C++ (ATL 9) باستخدام Visual Studio 2008.يقوم ملحق Shell بإنشاء كائن MSXML2::IXMLDOMDocumentPtr عمومي m_XmlDoc في فئة الوحدة النمطية.يتم بعد ذلك استخدام m_XmlDoc في الامتداد بواسطة جميع الفئات لقراءة مستند xml.

المشكلة التي أواجهها هي مع Internet Explorer.عندما يكون ملحق Shell نشطًا وأقوم بفتح/إغلاق Internet Explorer، يظهر لي مربع حوار تصحيح الأخطاء ويتعطل IE.تقول رسالة الخطأ "استثناء غير معالج في 0x6aac30f1 في iexplore.exe:0xC0000005:موقع قراءة الانتهاك 0x03050970. "عندما أنقر" استراحة "على نافذة الرسالة ، يأخذني إلى طريقة" الإصدار "للمؤشر الذكي ويبدو أن الخطأ على m_pinterface-> الإصدار () ؛

تم إجراء هذا الاستدعاء من أداة إتلاف الوحدة النمطية كما أن قيمة m_pInterface ليست فارغة.أعتقد أنه ربما يستخدم Internet Explorer XML DOM وأن استدعاء الإصدار يخلق بعض المشاكل فيه.

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); 
}
هل كانت مفيدة؟

المحلول 3

وكانت المشكلة بسبب مؤشر الذكية COM تستخدم لXmlDomDocument. لقد غيرت إلى المؤشر العادي وأنها تعمل بشكل جيد حتى في ويندوز فيستا.

وهذه مشكلة لها سلوك مختلف في XP وفيستا. في XP، الأول هو الحصول على استثناء غير معالج عندما أغلقت إنترنت إكسبلورر. في ويندوز فيستا، وأنا لم أكن قادرا على تصفح محرك الأقراص الظاهري.

نصائح أخرى

لا ينصح استخدام DisableThreadLibraryCalls، هل رأيت ذلك؟

هناك مشكلتان على الأقل في الكود الخاص بك كما تم نشره:

  1. أنت تقوم بالاتصال بـ CoInitialize في DllMain.
  2. أنت تقوم بإنشاء كائن COM في DllMain.
  3. لن يفاجئني إذا كنت تفعل شيئًا ما في CreateImageLists() والذي لا ينبغي عليك فعله أيضًا في DllMain.

أيضًا، السبب وراء "إصلاح" العطل لديك من خلال عدم استخدام المؤشر الذكي هو أنك الآن لم تعد تحرر الكائن فعليًا بعد الآن.الكود الخاص بك معطل، وعدم إصدار المرجع ليس طريقة صالحة لإصلاح أي شيء.

أود أن أقترح عليك قراءة الوثائق ثم إعادة قراءتها مرة أخرى DllMain مع إيلاء اهتمام خاص للأشياء التي لا ينبغي عليك فعلها مطلقًا أثناء تنفيذك للوظيفة.كما سترى في المقدمة:

تحذير هناك حدود جدية لما يمكنك القيام به في نقطة دخول DLL.لتوفير تهيئة أكثر تعقيدًا، قم بإنشاء روتين تهيئة لمكتبة الارتباط الحيوي (DLL).يمكنك مطالبة التطبيقات باستدعاء روتين التهيئة قبل استدعاء أية إجراءات أخرى في مكتبة الارتباط الديناميكي (DLL).

أظن أنه بمجرد قراءتها وإصلاح التعليمات البرمجية الخاصة بك لإنشاء كائن COM في وقت صالح، وإطلاقه في وقت صالح، سيتوقف ملحق Shell الخاص بك عن التعطل.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top