从同一台机器上的其他进程访问outproc COM服务器中的c#对象

时间:2012-09-11 09:43:34

标签: c# serialization com com-interop out-of-process

我试图从另一个进程访问C#对象而不是它们通过COM驻留的进程。 C#对象暴露给COM。

问题在于,当我在这些对象上调用方法时,调用是在本地执行的,而不是在outproc COM服务器上执行,我想要发生这些调用的副作用。

更确切地说,这是我在尝试访问驻留在outproc COM服务器中的对象的过程中所做的:

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

var obj = Activator.CreateInstance(oType);

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

然后我将结果转换为C#类的相应接口(IMyInterface),当我对该接口的方法进行调用时,它们就像我期望的那样在outproc COM服务器上远程执行。

当我使用该接口检索其他C#对象时,问题就开始了(我使用返回IMyInterface.GetOtherObject()的方法IOtherObjectInterface。)

当我在IOtherObjectInterface上进行调用时,它们在本地执行,而不是在outproc COM服务器上执行,因此它们的副作用会丢失(例如,如果我调用SetValue方法,则值不会到达outproc服务器上它失败了。)

此外,当我在运行时查看调试器时,我看到远程调用工作的接口类型是System._ComObject,而远程调用不起作用的接口类型是实际类型(IOtherObjectInterface)。

我试图复制所有关于IMyInterface(远程调用工作的方式)的方式(实现的所有属性和其他接口)在IOtherObjectInterface上向COM公开(一个用于哪些远程呼叫不起作用)但没有运气。

我必须做什么才能使我在IOtherObjectInterface上进行的调用通过RPC在outproc服务器中执行,而不是在本地进程(发出调用的进程)中执行,对任何人都没用? / p>

修改

我发现如果我使用与其工作的对象相同的方法检索它不起作用的对象(IOtherObjectInterface)(oType.InvokeMember(“GetOtherObjForMyClassMethod”) ,....)它仍然不起作用(我在对象上进行的调用仍未转发到outproc COM服务器)。

所以问题在于类本身,而不是用于检索对象的方法。

我强烈怀疑这个问题在某种程度上与序列化有关,即使这两个类(工作和不工作)似乎都以相同的方式实现序列化......

EDIT2:

我没有得到的部分是这个“COM远程处理”工作的类(当我在COM服务器外部检索对象时,我获得System._ComObject的那个)具有属性“serializable” 。我认为具有此属性的类型的默认值是marshal-by-value。

3 个答案:

答案 0 :(得分:0)

你需要根据Marc的答案使用ServicedComponent:

Create Out-Of-Process COM in C#/.Net?

答案 1 :(得分:0)

您可以做的是在组件服务控制台中创建一个新的应用程序,并声明它是一个进程外应用程序。为此,您需要

  1. 创建新的应用程序
  2. 右键单击此应用程序
  3. 转到“激活”选项卡,然后选择“服务器应用程序”
  4. 将您的DLL添加到此应用程序
  5. 您可能需要配置安全性。

答案 2 :(得分:0)

我已经确认,IMyInterface.GetOtherObject()远程执行,您的问题是为什么返回到您的调用代码的对象是实现IOtherObjectInterface的.NET类型的具体实例,而不是<{1}}或其他会导致对该对象进行方法调用的东西。

答案必须是System._ComObject实例化“OtherObject”,然后当它返回时,该实例正在编组到您的调用进程。如果对象是可序列化的.NET类型,则默认情况下会发生这种情况。

我认为如果对象是IMyInterface.GetOtherObject(),它将不会被编组回调用进程:调用代码将接收一个TransparentProxy,然后调用它将按照您的预期进行远程处理。 / p>

原始(MarshalByRefObject)对象是一种特殊情况,因为调用代码本身使用Activator和从ProgID派生的Type实例化它,并在COM Runtime的帮助下(引擎盖下)生成在特殊代理类型_ComObject。