Задача хостинга esoteric jscript: где код ошибки, когда IDispatch :: Invoke возвращает Script_e_Propagate?

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

Вопрос

Наше приложение размещает механизм Jscript хоста сценариев Windows и обнаруживает несколько доменных объектов, которые могут быть вызваны из кода скрипта.

Один из объектов домена представляет собой COM-компонент, который реализует Idispatch (фактически, IDispatchex), и который имеет метод, который имеет функцию скрипта в качестве параметра заднего вызова (IDispatch * в качестве параметра). Этот компонент COM вызывается скриптом, делает некоторые вещи, а затем вызовы обратно в скрипт через то, что прилагается параметр IDisPatch, прежде чем вернуться к сценарию вызова.

Если скрипт обратного списка происходит, чтобы бросить исключение (например, позвонит другому компоненту COM, который возвращает что-то другое, чем S_OK), то вызов idispatch :: Invoke на скрипте обратного списка вернет Script_e_Propagate вместо HResult от другого компонента COM; не ожидаемое гресурс от другого 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. Qi, чтобы получить Idispatchex. Указатель на функцию скрипта, которая будет называться.
  2. Построить объект, реализующий оба ISERVICEPROVIDER. & ICanhandleException.; например CSCripterRororCapturer..
    • ISERVICEPROVIDER :: QueryService может вернуть e_nointerface
    • Если скрипт обратный вызов функции бросает, но не поймает, исключение при invokex'd (см. Ниже), то ICanhandleException :: CanhandleException. получит excepinfo и вариант * (посмотрите на MSDN для документация).
    • Вариант будет содержать выброшенное объект, что может быть Ошибка объект.
    • Попробуйте получить свойства «Номер» и «Сообщение» от IDispatch на этом Ошибка Объект, где «номер» представляет собой фактическую ошибку скрипта (HRESULT).
    • Эти значения могут / должны быть использованы для обновления excepinfo распределять и (необязательно) bstrdescription. Для того, чтобы распространять ошибку до вызова скрипта. Если вы не обновляете распределять, Затем затем двигатель бросит «исключение, но не поймал» (0x800A139e), который является то, что содержит excePinfo, прежде чем изменить его.
    • Не уверен если pfndeferredfillin. следует очистить, но это работает без этого.
    • В моем коде я захватю ошибку здесь, в моем CSCripterROrcapter.
    • Return s_ok. Возвращая e_fail здесь будет прервать весь запуск скрипта, а не допустить исключения, чтобы быть брошенным обратно в исходный сценарий вызова.
  3. Call Idispatchex :: Involexex и пропустите свой CSCripterROrCapter в качестве параметра ISERVICEPROVIDER.
  4. По возвращении от Invokeex запрашивайте ваш CSCripterRororCapter, чтобы увидеть, поймал ли он ошибку. Согласно с код в GoogleWebkit, Иногда InvoleX может вернуть S_OK, даже если ошибка брошена.
  5. Не коснитесь возвращаемого значения от Involecex, особенно если это Script_e_Propagate (0x80020102)

Примечание: эта ссылка содержит некоторые из недокументированных jscript hresults, описанных выше.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top