مشكلة استضافة esiteric jscript: أين هو رمز الخطأ عند إرجاع idispatch :: invoke script_e_propagate؟

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

سؤال

يستضيف تطبيقنا محرك JScript Host Scripting Windows ويعرض العديد من كائنات المجال التي يمكن استدعاؤها من رمز البرنامج النصي.

أحد كائنات المجال هو مكون COM يقوم بتنفيذ IDISPATCH (في الواقع ، IDISPATCHEX) والذي يحتوي على طريقة تأخذ وظيفة نصية كمعلمة خلفية للاتصال (idispatch* كمعلمة). يتم استدعاء مكون com هذا بواسطة البرنامج النصي ، ويقوم ببعض الأشياء ، ثم يستدعي إلى البرنامج النصي عبر معلمة Idispatch المقدمة قبل العودة إلى البرنامج النصي.

إذا حدث أن البرنامج النصي للمكالمات يلقي استثناء (على سبيل المثال ، يقوم بإجراء مكالمة إلى مكون com آخر يعيد شيئًا آخر غير S_OK) ، فإن المكالمة إلى idispatch :: invoke على البرنامج النصي للاتصال ستُرجع script_e_propagate بدلاً من hresult من مكون com الآخر ؛ ليس hresult المتوقع من كائن com الآخر. إذا قمت بإرجاع هذا hresult (script_e_propagate) مرة أخرى إلى المتصل بمكون com الأول (على سبيل المثال ، إلى البرنامج النصي للاتصال) ، فإن محرك البرنامج النصي يلقي بشكل صحيح خطأ مع hresult المتوقع من كائن com الآخر.

ومع ذلك ، فإن خطأ فعلي ليس في أي مكان يمكن العثور عليه. لم يتم إرجاعها من استدعاء الاستدعاء (قيمة الإرجاع هي Script_E_Propagate). لم يتم إرجاعها عبر excepinfo المقدمة للاستدعاء (لا يزال الهيكل فارغًا). وهو غير متوفر عبر geterrorinfo (إرجاع المكالمة s_false)!

Script
    Defines ScriptCallback = function() { return ComComponentB.doSomething(); }
    Invokes ComComponentA.execute(ScriptCallback)
        Invokes ScriptCallback()
            Invokes ComComponentB.doSomething()
                Returns E_FAIL (or some other HRESULT)
            Throws returned HRESULT
        Receives SCRIPT_E_PROPAGATE <--- WHERE IS THE ACTUAL ERROR?
        Returns SCRIPT_E_PROPAGATE
    Throws E_FAIL (or whatever HRESULT was returned from ComComponentB)

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

هل كانت مفيدة؟

المحلول

واو ، كان هذا غير موثقة بشكل خطير.

الجواب هو:

في مكون COM يقوم بإجراء رد اتصال في البرنامج النصي ...

  1. تشي للحصول على idispatchex مؤشر على وظيفة البرنامج النصي ليتم استدعاؤه.
  2. بناء كائن ينفذ كليهما iserviceprovider & icanhandleexception; ؛ على سبيل المثال cscripterrorcapturer.
    • iserviceprovider :: QueryService يمكن إرجاع E_Nointerface
    • إذا كانت دالة رد الاتصال السينمائية ترمي ، ولكنها لا تصطاد ، استثناء عند استدعاء (انظر أدناه) ، ثم icanhandleexception :: canhandleexception سيحصل على excepinfo و variant* (انظر إلى MSDN توثيق).
    • سيحتوي المتغير على الكائن الذي قد يكون خطأ هدف.
    • حاول الحصول على خصائص "الرقم" و "الرسالة" من Idispatch في هذا خطأ كائن ، حيث يمثل "الرقم" خطأ البرنامج النصي الفعلي (HRESULT).
    • يمكن/يجب استخدام هذه القيم لتحديث excepinfo سكود و (اختياريا) Bstrdescription من أجل نشر الخطأ حتى البرنامج النصي استدعاء. إذا لم تقم بتحديث سكود, ، بعد ذلك ، سيقوم المحرك بإلقاء "استثناء تم إلقاؤه ولكن لم يتم القبض عليه" (0x800A139E) ، وهو ما يحتويه excepinfo قبل تعديله.
    • ليس متأكدا مما اذا pfndeferredfillin يجب مسح ، لكنه يعمل دون القيام بذلك.
    • في الكود الخاص بي ، ألتقط الخطأ هنا في cscripterrorcapturer.
    • إرجاع S_OK. سيؤدي إرجاع e_fail إلى إحباط تشغيل البرنامج النصي بأكمله ، ولا يسمح بإعداد الاستثناء إلى البرنامج النصي الأصلي.
  3. اتصل بـ Idispatchex :: InvokeEx وتمرير cscripterrorcapturer كمعلمة iserviceprovider.
  4. عند العودة من InvokeEx ، استعد cscripterrorcapturer لمعرفة ما إذا كان قد وقع خطأ. وفق رمز في googlewebkit, ، في بعض الأحيان قد يعيد InvokeEx S_OK ، حتى إذا تم طرح خطأ.
  5. لا تلمس قيمة الإرجاع من InvokeEx ، خاصة إذا كانت Script_E_Propagate (0x80020102)

ملحوظة: هذا الرابط يحتوي على بعض من hresults Jscript غير الموثقة الموصوفة أعلاه.

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