3

私はこのexe comサーバーを使用しています:

https://cfx.svn.codeplex.com/svn/Visual%20Studio%202008/CSExeCOMServer/ExeCOMServer.cs

  • 私のプログラムはcomアプリです
  • 別のcomオブジェクトを取る私のcomメソッドはvoid Init(AppsScriptRunningContext rc);
  • このメソッドでは、プロパティを読み出そうとすると、このエラーが発生します

タイプ 'AppsScriptLib.AppsScriptRunningContextClass' の COM オブジェクトをインターフェイス タイプ 'AppsScriptLib.IAppsScriptRunningContext' にキャストできません。IID '{4D2E5723-87C2-49C1-AA28-ED2D88275100}' を持つインターフェイスの COM コンポーネントでの QueryInterface 呼び出しが次のエラーにより失敗したため、この操作は失敗しました: No such interface supported (HRESULT からの例外: 0x80004002 (E_NOINTERFACE))

私のアプリが com サーバーではなく、通常の com アプリである場合、エラーは発生しません。そのため、エラーはexe comサーバーによって生成されたと思います。

https://cfx.svn.codeplex.com/svn/Visual%20Studio%202008/CSExeCOMServer/ExeCOMServer.cs

よろしく、クリス

4

2 に答える 2

7

これは非常に残念なコード サンプルであり、成功する可能性は非常にゼロに近いです。これは MSDN フォーラム サポート グループの製品であり、彼らの作業は Microsoft でピア レビューされていません。あるチーム メンバーは、これが正しい方法ではないことを後で認めました。

このコードの問題は、RegistrationServices.RegisterTypeForComClients() メソッドに関する MSDN ドキュメントの Remark を完全に無視することです。

COM オブジェクトの登録と登録解除のために、プラットフォーム呼び出しを使用してアンマネージ CoRegisterClassObject メソッドと CoDisconnectObject メソッドを呼び出すことはサポートされていないことに注意してください。

残念ながら、サポートされていない理由を説明していません。重要な問題は、アウト プロセス アクティベーションの場合、COM インターフェイスを常にマーシャリングする必要があることです。これは、クライアント側でプロキシを作成することによって行われます。これは、元のインターフェイスと同じメソッドをすべて持つが、実装されたメソッドがメソッドの引数を RPC 経由で他のプロセスに送信するインターフェイスのインスタンスです。サーバー側では、スタブは同じですが反対の役割を果たし、メソッド引数を使用してスタック フレームを構築し、実際のメソッド呼び出しを行います。

プロキシとスタブの作成は .NET で非常に簡単です。リフレクションを使用すると簡単になります。フレームワークに組み込まれた Remoting 配管によって実行されます。ただし、COM では簡単ではありません。リフレクションに似たものはありません。これを行う基本的な方法は 2 つあります。まず、COM インターフェイス定義を IDL 言語で記述し、それを midl.exe でコンパイルします。これにより、DLL をビルドできるマーシャリングを行う C ソース コードが自動的に生成されます。次に、その DLL を HKCR\Interface レジストリ キーに適切に登録して、インターフェイスのマーシャリングが必要なときにいつでも COM が DLL を見つけてロードできるようにする必要があります。2 番目の方法は、インターフェイスが IDispatch から派生し、OLE オートメーションと互換性のある引数の型に制限されている場合に使用できます。その後、タイプ ライブラリを生成し、標準のマーシャラーを使用できます。

これは、.NET アウトプロセス サーバーでは発生しない部分です。プロキシ/スタブ DLL を生成するのに役立つ midl.exe がなく、標準マーシャラーを使用するための登録ヘルプが表示されません。これは、エラー メッセージが実際に言っていることです。ここで E_NOINTERFACE は、インターフェイスをマーシャリングする方法が見つからなかったことを意味します。はい、くだらないエラー メッセージです。

アウトプロセス COM サーバーを作成するために .NET で公式にサポートされている方法は、それを COM+ に登録することです。System.EnterpriseServices.ServicedComponent クラスを基本クラスとして使用します。MSDN ライブラリの記事はこちらです。

于 2012-05-27T13:31:46.930 に答える
1

メインスレッドを変更するようアドバイスをもらい、助かりました!

メイン スレッド (ほとんどは "Program.cs" にあります) で [STAThread] 行を見つけて、[MTAThread] に変更します。

于 2013-06-25T12:24:53.667 に答える