代码之家  ›  专栏  ›  技术社区  ›  James Hugard

神秘的JScript托管问题:当IDispatch::Invoke返回脚本时,错误代码在哪里?

  •  2
  • James Hugard  · 技术社区  · 14 年前

    我们的应用程序托管Windows脚本主机JScript引擎,并公开几个可以从脚本代码调用的域对象。

    其中一个域对象是实现IDispatch(实际上是IDispatchEx)的COM组件,它有一个将脚本函数作为回调参数(IDispatch*作为参数)的方法。这个COM组件由脚本调用,执行一些操作,然后在返回到调用脚本之前,通过提供的IDispatch参数回调到脚本中。

    如果回调脚本碰巧抛出异常(例如,对另一个COM组件进行调用,该组件返回的不是Sïu OK),那么回调脚本上对IDispatch::Invoke的调用将返回scriptïeïu PROPAGATE,而不是来自另一个COM组件的HRESULT;不是来自其他COM对象的预期HRESULT。如果我将该HRESULT(SCRIPT\u E\u PROPAGATE)返回给第一个COM组件的调用者(例如,返回到调用脚本),那么脚本引擎将正确地抛出一个错误,其中包含来自另一个COM对象的预期HRESULT。

    实际误差

    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组件在调用回提供的脚本函数的过程中获得抛出的异常???

    1 回复  |  直到 14 年前
        1
  •  2
  •   Eric Lippert    4 年前

    哇,这是严重的文件不足。

    答案是:

    1. 齐去拿一个 伊迪斯帕切克斯
    2. IServiceProvider服务器 ICanHandleException异常 ; 例如 .
      • IServiceProvider::查询服务 无法返回E\u NOINTERFACE
      • 如果脚本回调函数在InvokEx'd(见下文)时抛出但未捕获异常,则 ICanHandleException::CanHandleException documentation
      • 变量将包含抛出的对象,该对象可能是 对象。
      • 错误 对象,其中“number”表示实际脚本错误(HRESULT)。
      • 这些值可以/应该用于更新exepinfo 斯科德 B说明 以便将错误传播到调用脚本。如果你不更新 ,然后引擎将抛出一个“Exception抛出但未捕获”(0x800A139E),这是在修改EXCEPINFO之前EXCEPINFO包含的内容。
      • pfnDeferredFillIn公司 应该被清除,但它不这样做。
      • 在我的代码中,我在cscripterrocrapturer中捕获错误。
    3. 调用IDispatchEx::InvokeEx并将cscriptorCapturer作为IServiceProvider参数传递。
    4. 从InvokeEx返回后,查询您的cscripterroccapturer以查看它是否捕获到错误。根据 code in the GoogleWebKit
    5. 不要接触InvokeEx的返回值,特别是如果它是SCRIPT\u E\u PROPAGATE(0x80020102)

    注: this link 包含上面描述的一些未记录的JScript HRESULT。