C#アクティブオートメーションオブジェクトの実行-イベントを調達する方法は?

クレリック

C#で記述された(長時間実行されている)コンソールアプリケーションがあり、COMを介して操作できるようにします(したがって、InProc DLLとregasm.exeはありません)。IDispatch必要なのはこれだけです。つまり、従来のOLEオートメーションオブジェクトです。

ここでは、私がやろうとしていることの最小限のバージョンを紹介します。私は次のようなCOMクラスを定義しました:

[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
[Guid("9009311a-c0b2-42a4-8e7c-f42091d71594")]
public interface ITestEvents {
    void OnEvent();
}

[ComVisible(true)]
[ClassInterface(ClassInterfaceType.AutoDispatch)]
[ComSourceInterfaces(typeof(ITestEvents))]
public class ComClass {
    public event Action OnEvent;

    public int Test() {
        return 100;
    }
}

ではMain()、Running Object Table(ROT)のオブジェクトを"comTestApp"Monikerに登録し、アプリケーションをスリープ状態にします。あなたはここで完全なソースを見ることができます

これは、オブジェクトのメソッドを呼び出そうとすると問題なく機能します。たとえば、このVBScriptは正常に機能します。

Set obj = GetObject("comTestApp")
WScript.Echo obj.Test() Rem prints 100

しかし、私がイベントを接続しようとすると:

Set obj = GetObject("comTestApp")
WScript.Echo obj.Test() Rem Works

WScript.ConnectObject obj, "obj_" Rem Fails

Sub obj_OnEvent
    WScript.Echo "Wish it worked"
End Sub

呼び出し時にエラーが発生しますConnectObject(エラー0x80020009「オブジェクトを接続できませんでした」)。

アセンブリをInProcオブジェクトとしてregasm.exeに登録すると、同じコード(クラスGUID / ProgIDのみを追加する必要があります)が機能しますが、それは必要ありません。実行中のアプリケーションにアクセスする必要があるため、ROTを使用します。

簡単なC ++テストを作成して、問題についてもっと知ることができるかどうかを確認しました。ソースはこちらです。IDispatchイベントシンクとして機能するインターフェイスを実装する最小限のCOMオブジェクトを作成しました最初にROTからオブジェクトを取得し、をクエリしてから、のIIDをIConnectionPointContainer取得IConnectionPointITestEvents、最後にそのAdvise()メソッドを呼び出しますVBScriptと同様に、失敗します(ただし、別のエラー-0x80040202が発生します)。QueryInterfaceイベントシンクのメソッドにブレークポイントを設定して、Advise()が呼び出されたときに何が起こるかを確認しましたこれはQueryInterfaceさまざまなインターフェイスで呼び出され、最後に要求されITestEvents、それを返してステータスを設定しいることがわかりますS_OKそれでも、Advise()メソッドは上記のエラーを返します。

私はまた別のものを試してみました:私は、GUIDの設定したITestEvents{00020400-0000-0000-C000-000000000046}いるのIIDですIDispatchそして今、Advise()戻りますS_OKイベントをシミュレートしたところInvoke()、イベントシンクのメソッドが呼び出されました。残念ながら、これは一般的に問題を解決しません。IConnectionPointContainerIIDから直接リクエストすると、取得できますが、によって正しく列挙されていないようでITypeInfo、VBScriptはまだ機能しません。

COMの経験がほとんどないので、ここからどこに行けばいいのかわかりません。IDispatchIIDを使用すると機能するので、ITestEventsインターフェイスにカスタムマーシャリングが必要かどうか疑問IDispatchに思いますが、純粋なので、ランタイムで適切に処理する必要があると思います。

ありがとうございました!

クレリック

私の結論は、インターフェイスIIDがレジストリに登録されていない接続シンクを(プロセス外オブジェクトに)提供することはできないということです。

シンクインターフェイスをサーバーに送信するには、マーシャリング情報が必須のようです。C#クラスが完全に提供するITypeInfoので、COMランタイムがインターフェイスがIDispatch型であると認識し、デフォルトのプロキシを使用することを期待していました残念ながら、これは当てはまらないように思われるので、唯一のオプションはレジストリです。

最低限、これが必要であることがわかりました。

[HKEY_CLASSES_ROOT\Interface\{9009311a-c0b2-42a4-8e7c-f42091d71594}\ProxyStubClsid32]
@="{00020424-0000-0000-C000-000000000046}"

これはイベントインターフェイスを定義し、プロキシに標準のIDispatchプロキシを使用することを示しています。

私はこれをWindows7と10でテストしましたが、動作します。--VBScriptは可能でConnectObjectあり、すべてが正常に機能します。

偶然、これが機能しないWin7インストールを見つけました(win ver6.1ビルド7601sp1)。タイプライブラリ(regasm.exe /tlb)を登録した後にのみ機能しました問題のインストールではWindowsUpdateが無効になっている(他のWin7は完全に更新されている)ので、デフォルトのIDispatchプロキシを指定していることに基づいて、ある時点で何かが変更され、タイプライブラリがなくてもインターフェイスをマーシャリングできるようになると思います。

最後に、アプリを移植可能でレジストリから独立させたいので、手動のイベント実装に頼りました。似たようなものがここに見られます

この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。

侵害の場合は、連絡してください[email protected]

編集
0

コメントを追加

0

関連記事

分類Dev

子オブジェクトのアニメーション

分類Dev

関数Bの実行コンテキストがそのアクティベーションオブジェクトを関数に渡さない理由スコープチェーンオブジェクトとして、そのAはBの変数にアクセスします

分類Dev

複数のアニメーションオブジェクトをチェーンする方法は?

分類Dev

オブジェクトのプロパティはC#のオブジェクトでガベージコレクションされますか、それとも個別のgcメカニズムがありますか

分類Dev

ドメインオブジェクトとプレゼンテーションオブジェクト間の対応を維持する方法

分類Dev

アクティブなレコードリレーションからのオブジェクト属性の表示

分類Dev

Deeplab:重複するオブジェクトのセグメンテーションを分離する方法は?

分類Dev

JS関数は、オブジェクトを入力として受け取り、パラメーターとして渡されたオブジェクトに対してアクションを実行するオブジェクトを返します。

分類Dev

同じクラスの複数のオブジェクトをアニメーション化する方法は?

分類Dev

C#でアクティブオブジェクトパターンTypedActorを作成する方法

分類Dev

UNITY3D 同じオブジェクトで同時に複数のアニメーションを実行する方法は?

分類Dev

(UWP)Flyoutオブジェクトをアニメーション化する方法

分類Dev

結果をStruts2でオブジェクトを返すアクションのreturnステートメントと一致させる方法は?

分類Dev

ネストされたコレクション内のオブジェクトプロパティを、C#ドライバーを使用してMongoDB内のこのオブジェクトの別のプロパティで更新する

分類Dev

C#でオブジェクトのクローンを作成してメモリキャッシュを実行する方法

分類Dev

Kineticjsでカーブパス上のオブジェクトをアニメーション化する方法

分類Dev

CloudFormationテンプレートのオブジェクト全体をオプションにする方法は?

分類Dev

実際のWebアプリケーションでのプロパティ/メソッドのオブジェクト指向の使用?

分類Dev

サードパーティのCOM(ActiveX)オブジェクトを使用するC#アプリケーションをデプロイすると、アプリケーションがクラッシュします

分類Dev

C ++なぜベクトルセグメンテーションフォールトにオブジェクトを配置するのですか?

分類Dev

WindowsPhoneのオブジェクトのランダムアニメーション

分類Dev

流域セグメンテーション後のオブジェクトの抽出

分類Dev

オブジェクトのセットがアクションを実行したかどうかを効率的に判断するためのデザインパターンまたは言語機能(c#)はありますか?

分類Dev

Unityオブジェクトの位置をフリーズせずに、オブジェクトの位置をアニメーション化する方法

分類Dev

Mockitoモックアノテーション複数のオブジェクト

分類Dev

C ++オブジェクトセグメンテーション違反(コアダンプ)エラー

分類Dev

重複するキーでjavascriptオブジェクトでアクションを実行する

分類Dev

Javaでは、オブジェクトがガベージコレクションのルートからまだ到達可能かどうかを調べる方法はありますか?

分類Dev

ディクショナリからオブジェクトメンバーの値を取得する方法

Related 関連記事

  1. 1

    子オブジェクトのアニメーション

  2. 2

    関数Bの実行コンテキストがそのアクティベーションオブジェクトを関数に渡さない理由スコープチェーンオブジェクトとして、そのAはBの変数にアクセスします

  3. 3

    複数のアニメーションオブジェクトをチェーンする方法は?

  4. 4

    オブジェクトのプロパティはC#のオブジェクトでガベージコレクションされますか、それとも個別のgcメカニズムがありますか

  5. 5

    ドメインオブジェクトとプレゼンテーションオブジェクト間の対応を維持する方法

  6. 6

    アクティブなレコードリレーションからのオブジェクト属性の表示

  7. 7

    Deeplab:重複するオブジェクトのセグメンテーションを分離する方法は?

  8. 8

    JS関数は、オブジェクトを入力として受け取り、パラメーターとして渡されたオブジェクトに対してアクションを実行するオブジェクトを返します。

  9. 9

    同じクラスの複数のオブジェクトをアニメーション化する方法は?

  10. 10

    C#でアクティブオブジェクトパターンTypedActorを作成する方法

  11. 11

    UNITY3D 同じオブジェクトで同時に複数のアニメーションを実行する方法は?

  12. 12

    (UWP)Flyoutオブジェクトをアニメーション化する方法

  13. 13

    結果をStruts2でオブジェクトを返すアクションのreturnステートメントと一致させる方法は?

  14. 14

    ネストされたコレクション内のオブジェクトプロパティを、C#ドライバーを使用してMongoDB内のこのオブジェクトの別のプロパティで更新する

  15. 15

    C#でオブジェクトのクローンを作成してメモリキャッシュを実行する方法

  16. 16

    Kineticjsでカーブパス上のオブジェクトをアニメーション化する方法

  17. 17

    CloudFormationテンプレートのオブジェクト全体をオプションにする方法は?

  18. 18

    実際のWebアプリケーションでのプロパティ/メソッドのオブジェクト指向の使用?

  19. 19

    サードパーティのCOM(ActiveX)オブジェクトを使用するC#アプリケーションをデプロイすると、アプリケーションがクラッシュします

  20. 20

    C ++なぜベクトルセグメンテーションフォールトにオブジェクトを配置するのですか?

  21. 21

    WindowsPhoneのオブジェクトのランダムアニメーション

  22. 22

    流域セグメンテーション後のオブジェクトの抽出

  23. 23

    オブジェクトのセットがアクションを実行したかどうかを効率的に判断するためのデザインパターンまたは言語機能(c#)はありますか?

  24. 24

    Unityオブジェクトの位置をフリーズせずに、オブジェクトの位置をアニメーション化する方法

  25. 25

    Mockitoモックアノテーション複数のオブジェクト

  26. 26

    C ++オブジェクトセグメンテーション違反(コアダンプ)エラー

  27. 27

    重複するキーでjavascriptオブジェクトでアクションを実行する

  28. 28

    Javaでは、オブジェクトがガベージコレクションのルートからまだ到達可能かどうかを調べる方法はありますか?

  29. 29

    ディクショナリからオブジェクトメンバーの値を取得する方法

ホットタグ

アーカイブ