1

我试图从另一个进程访问 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)时,问题就开始了。

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

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

我试图复制关于方式IMyInterface(远程调用工作的那个)暴露给COM IOtherObjectInterface(远程调用不起作用的那个)的所有内容(所有属性和其他实现的接口),但没有运气。

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

编辑

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

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

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

编辑2:

我没有得到的部分是这个“COM远程处理”工作的类(当我在COM服务器外部检索对象时获得System._ComObject的类)具有“可序列化”属性。我认为具有此属性的类型的默认值是按值封送。

4

3 回答 3

0

You have confirmed, I think, that IMyInterface.GetOtherObject() executes remotely, and your question is why the object returned to your calling code is a concrete instance of the .NET type implementing IOtherObjectInterface, rather than being a System._ComObject or something else which would cause method calls on that object to be remoted.

The answer must be that IMyInterface.GetOtherObject() instantiates the "OtherObject" and then when it returns, that instance is being marshalled to your calling process. This will happen by default if the object is of a serializable .NET type.

I think that if the object were a MarshalByRefObject, it wouldn't be marshalled back to the calling process: the calling code would receive instead a TransparentProxy and then calls on it would be remoted as you expect.

The original (IMyInterface) object is a special case because the calling code itself instantiates this, using the Activator and a Type derived from the ProgID, with the assistance (under the hood) of the COM Runtime, resulting in the special proxy type _ComObject.

于 2012-09-12T11:06:59.907 回答
0

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

  1. 创建一个新的应用程序
  2. 右键单击此应用程序
  3. 转到“激活”选项卡,然后选择“服务器应用程序”
  4. 将您的 DLL 添加到此应用程序

您可能必须配置安全性。

于 2012-09-11T12:48:14.080 回答
0

您需要按照 Marc 在此处的回答使用 ServicedComponent:

在 C#/.Net 中创建进程外 COM?

于 2012-09-11T09:48:17.640 回答