深奥的 JScript 托管问题:IDispatch::Invoke 返回 SCRIPT_E_PROPAGATE 时的错误代码在哪里?
我们的应用程序托管 Windows Scripting Host JScript 引擎,并公开多个可以从脚本代码调用的域对象。
其中一个域对象是一个 COM 组件,它实现了 IDispatch(实际上是 IDispatchEx),并且具有一个将脚本函数作为回调参数(IDispatch* 作为参数)的方法。该 COM 组件由脚本调用,执行一些操作,然后通过提供的 IDispatch 参数回调到脚本,然后返回到调用脚本。
如果回调脚本碰巧抛出异常(例如,调用另一个 COM 组件,该组件返回 S_OK 以外的内容),则回调脚本上对 IDispatch::Invoke 的调用将返回 SCRIPT_E_PROPAGATE 而不是 HRESULT来自其他 COM 组件;不是来自其他 COM 对象的预期 HRESULT。如果我将该 HRESULT (SCRIPT_E_PROPAGATE) 返回给第一个 COM 组件的调用者(例如,调用脚本),则脚本引擎会正确地抛出来自其他 COM 对象的预期 HRESULT 的错误。
然而,实际错误却无处可寻。它不会从 Invoke 调用返回(返回值为 SCRIPT_E_PROPAGATE)。它不会通过提供给 Invoke 的 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 组件在回调提供的脚本函数期间抛出异常?
Our application hosts the Windows Scripting Host JScript engine and exposes several domain objects that can be called from script code.
One of the domain objects is a COM component that implements IDispatch (actually, IDispatchEx) and which has a method that takes a script-function as a call-back parameter (an IDispatch* as a parameter). This COM component is called by script, does some things, and then calls back into script via that supplied IDispatch parameter before returning to the calling script.
If the call-back script happens to throw an exception (e.g., makes a call to another COM component which returns something other than S_OK), then the call to IDispatch::Invoke on the call-back script will return SCRIPT_E_PROPAGATE instead of the HRESULT from the other COM component; not the expected HRESULT from the other COM object. If I return that HRESULT (SCRIPT_E_PROPAGATE) back to the caller of the first COM component (e.g., to the calling script), then the script engine correctly throws an error with the expected HRESULT from the other COM object.
However, the ACTUAL ERROR is nowhere to be found. It's not returned from the Invoke call (the return value is SCRIPT_E_PROPAGATE). It's not returned via the EXCEPINFO supplied to Invoke (the structure remains empty). AND, it's not available via GetErrorInfo (the call returns 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)
I'd really like to get my hands on that error, because it would be useful to cache it and return the same error on subsequent calls (getting to the error often involves an expensive operation that is defined by the script-function passed as a parameter, but I do know how to cache the error). Is there a way for a scripted COM component to get to an exception thrown during a call-back into a supplied script-function???
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
哇,这记录严重不足。
答案是:
在 COM 组件中对脚本进行回调...
注意:此链接包含上述一些未记录的 JScript HRESULTS。
Wow, this was seriously underdocumented.
The answer is to:
In the COM component making a callback into script...
Note: this link contains some of the undocumented JScript HRESULTS described above.