難解なJScriptのホスティング問題:IdisPatch :: Invoke returns Script_e_propagateの場合、エラーコードはどこにありますか?

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

質問

アプリケーションは、Windows Scripting Host JScriptエンジンをホストし、スクリプトコードから呼び出すことができるいくつかのドメインオブジェクトを公開します。

ドメインオブジェクトの1つは、IdisPatch(実際、IdisPatchex)を実装するCOMコンポーネントであり、コールバックパラメーター(パラメーターとしてIdisPatch*)としてスクリプト機能を取るメソッドがあります。このcomコンポーネントはスクリプトによって呼び出され、いくつかのことを行い、その後、呼び出しのスクリプトに戻す前に、その提供されたidispatchパラメーターを介してスクリプトに呼び戻します。

コールバックスクリプトが例外をスローする場合(たとえば、s_ok以外の何かを返す別のcomコンポーネントに呼び出します)、idispatch :: call-backスクリプトの呼び出しはhresultの代わりにscript_e_propagateを返します他のcomコンポーネントから。他のcomオブジェクトからの予想されるhresultではありません。そのhresult(script_e_propagate)を最初のcomコンポーネントの呼び出し元(たとえば、呼び出しスクリプト)に戻すと、スクリプトエンジンは他のcomオブジェクトから予想されるhresultでエラーを正しくスローします。

しかし 実際のエラー どこにも見つかりません。 Invokeコールから返されません(返信値は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;例えば cscripterrorcapturer.
    • iServiceProvider :: QueryService e_nointerfaceを返すことができます
    • スクリプトコールバック関数がスローしますが、キャッチしない場合、InvokeX'd(以下を参照)が例外です。 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. 特にscript_e_propagate(0x80020102)の場合、invokeexからの返品値に触れないでください

ノート: このリンク 上記の文書化されていないJScript hresultsの一部が含まれています。

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top