1

COM経由で存在するプロセスとは別のプロセスからC#オブジェクトにアクセスしようとしています。C#オブジェクトはCOMに公開されます。

問題は、これらのオブジェクトでメソッドを呼び出すと、これらの呼び出しの副作用を発生させたいoutproc COMサーバーではなく、ローカルで呼び出しが実行されることです。

より正確には、outprocCOMサーバーにあるオブジェクトにアクセスしようとするプロセスで私が行うことは次のとおりです。

Type oType = Type.GetTypeFromProgID("myProgId");

var obj = Activator.CreateInstance(oType);

var result = oType.InvokeMember("GetObjForMyClassMethod",
                                BindingFlags.InvokeMethod, null, obj, null);

次に、結果をIMyInterfaceC#クラスの適切なインターフェイス()にキャストし、そのインターフェイスのメソッドを呼び出すと、期待どおりにoutprocCOMサーバーでリモートで実行されます。

このインターフェイスを使用して他のC#オブジェクトを取得すると、問題が発生します(をIMyInterface.GetOtherObject()返すメソッドを使用しますIOtherObjectInterface)。

で呼び出しを行うとIOtherObjectInterface、outproc COMサーバーではなくローカルで実行されるため、副作用が失われます(たとえば、SetValueメソッドを呼び出すと、値がoutprocサーバーに到着せず、失われます)。

さらに、実行時にデバッガーを確認すると、リモート呼び出しが機能System._ComObjectするインターフェイスのタイプが実際のタイプ(IOtherObjectInterface)であるのに対し、リモート呼び出しが機能しないインターフェイスのタイプは実際のタイプであることがわかります。

私はIMyInterface(リモート呼び出しが機能するもの)がCOMに公開される方法(IOtherObjectInterfaceリモート呼び出しが機能しないもの)についてすべて(実装されているすべての属性と他のインターフェイス)を複製しようとしましたが、運がありません。

私が行うIOtherObjectInterface呼び出しが、誰にも使用されないローカルプロセス(呼び出しが発行されるプロセス)ではなく、RPCを介してoutprocサーバーで実行されるようにするにはどうすればよいですか?

編集

それ以来、機能しないオブジェクト(IOtherObjectInterface)を、機能するオブジェクトに使用するのと同じメソッド(oType.InvokeMember( "GetOtherObjForMyClassMethod"、....))を使用して取得した場合でも、それが機能することがわかりました。動作しません(オブジェクトに対して行った呼び出しは、まだoutproc COMサーバーに転送されません)。

したがって、問題はクラス自体にあり、オブジェクトの取得に使用されるメソッドにはありません。

両方のクラス(機能しているクラスと機能していないクラス)が同じ方法でシリアル化を実装しているように見えても、この問題は何らかの形でシリアル化に関連していると強く思います...

EDIT2:

私が得られない部分は、この「COMリモーティング」が機能するクラス(COMサーバーの外部でオブジェクトを取得するときにSystem._ComObjectを取得するクラス)が属性「serializable」を持っているという事実です。この属性を持つタイプのデフォルトは、値によるマーシャルだと思いました。

4

3 に答える 3

0

あなたはそれがリモートで実行されることを確認したと思いIMyInterface.GetOtherObject()ます、そしてあなたの質問は、あなたの質問は、あなたの呼び出し元のコードに返されるオブジェクトが、そのオブジェクトのメソッド呼び出しを引き起こすような何かIOtherObjectInterfaceではなく、実装する.NETタイプの具体的なインスタンスである理由ですSystem._ComObjectリモートになります。

答えはIMyInterface.GetOtherObject()、「OtherObject」をインスタンス化し、それが戻ったときに、そのインスタンスが呼び出しプロセスにマーシャリングされているということである必要があります。これは、オブジェクトがシリアル化可能な.NETタイプの場合、デフォルトで発生します。

オブジェクトがである場合MarshalByRefObject、それは呼び出し元のプロセスにマーシャリングされないだろうと思います。呼び出し元のコードは代わりにTransparentProxyを受信し、それに対する呼び出しは期待どおりにリモート化されます。

元の(IMyInterface)オブジェクトは特殊なケースです。これは、呼び出し元のコード自体が、アクティベーターとProgIDから派生したTypeを使用して、COMランタイムの支援を受けて(内部で)これをインスタンス化し、特別なプロキシタイプ_ComObjectを生成するためです。

于 2012-09-12T11:06:59.907 に答える
0

ここでのマークの回答に従って、ServicedComponent を使用する必要があります。

C#/.Net でアウトプロセス COM を作成しますか?

于 2012-09-11T09:48:17.640 に答える
0

できることは、コンポーネント サービス コンソールで新しいアプリケーションを作成し、それがプロセス外アプリケーションであることを宣言することです。このためには、次のことが必要です。

  1. 新しいアプリケーションを作成する
  2. このアプリケーションを右クリック
  3. [アクティベーション] タブに移動し、[サーバー アプリケーション] を選択します。
  4. このアプリケーションに DLL を追加します

セキュリティを構成する必要がある場合があります。

于 2012-09-11T12:48:14.080 に答える