深奥的JScript托管问题:IDISPATCH :: INDOKE返回script_e_propagate时的错误代码在哪里?

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

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

域对象之一是一个COM组件,该组件实现IDISPATCH(实际上,IDISPATCHEX),并且具有将脚本函数作为呼叫返回参数(IDISPATCH*作为参数)的方法。此COM组件由脚本调用,做一些事情,然后在返回调用脚本之前通过提供的IDISPATCH参数回到脚本中。

如果呼叫脚本恰好抛出异常(例如,对另一个返回s_ok以外的东西的com组件进行呼叫),则呼叫call to dispatch ::在呼叫back脚本上invoke将返回script_e_propagate,而不是hresult hresult从其他com组件中;不是另一个com对象的预期hresult。如果我将hresult(script_e_propagate)返回回到第一个com组件的呼叫者(例如,呼叫脚本),则脚本引擎正确地从另一个com对象的预期hresult丢弃了错误。

然而 实际错误 找不到任何地方。它没有从调用调用中返回(返回值为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)

ID 真的 想让我掌握该错误,因为将其缓存并在后续呼叫上返回相同的错误是有用的(进入错误通常涉及由脚本函数通过作为参数定义的昂贵操作,但是我知道如何缓存错误)。有没有办法让脚本的COM组件在呼叫过程中获得一个异常,以提供提供的脚本功能???

有帮助吗?

解决方案

哇,这是严重记录的。

答案是:

在com组件中,将回调为脚本...

  1. qi得到一个 IDISPATCHEX 脚本函数的指针被调用。
  2. 构建一个实现的对象 IserviceProvider & icanhandleexception;例如 cscripterrorcapturer.
    • IserviceProvider :: QueryService 可以返回e_nointerface
    • 如果脚本回调函数投掷但没有捕获,则在Invokex'd(见下文)时,则 icanhandleexception :: canhandleexception 将获得一个excepinfo和variant*(在MSDN上查找 文档).
    • 该变体将包含抛出的对象,这可能是 错误 目的。
    • 尝试从IDISPATCH上获取“数字”和“消息”属性 错误 对象,其中“数字”代表实际的脚本错误(hresult)。
    • 这些值可以/应该用于更新excepinfo scode (可选) Bstrdescription 为了将错误传播到调用脚本。如果您不更新 scode, ,然后发动机将抛出“抛出但未捕获的异常”(0x800A139E),这是Excepinfo在修改之前所包含的内容。
    • 不知道 pfndeferredfillin 应该清除,但它不做此操作。
    • 在我的代码中,我在CSCRIPTERRORCAPTURER中捕获了此错误。
    • 返回S_OK。返回的e_fail在这里将中止整个脚本运行,并且不允许将异常放回原始调用脚本。
  3. 调用IDISPATCHEX :: INDOKEEX,然后将您的CSCRIPTERRORCAPTURER作为IserviceProvider参数。
  4. 从Invokeex返回后,请查询您的CSCRIPTERRORCAPTURER,以查看是否遇到了错误。根据 Googlewebkit中的代码, ,有时即使出现错误,InvokeEx也可能返回S_OK。
  5. 不要从Invokeex触摸返回值,尤其是如果是script_e_propagate(0x80020102)

笔记: 这个链接 包含上述一些无证件的JScript Hresults。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top