Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/269.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
从同一台机器上的其他进程访问outproc COM服务器中的c#对象_C#_Serialization_Com_Com Interop_Out Of Process - Fatal编程技术网

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

从同一台机器上的其他进程访问outproc COM服务器中的c#对象,c#,serialization,com,com-interop,out-of-process,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 r

我试图从另一个进程访问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#对象时,问题就开始了(我使用返回
IOtherObjectInterface
的方法
IMyInterface.GetOtherObject()

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

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

我已经尝试复制了所有关于
IMyInterface
(远程调用工作的接口)在
IOtherObjectInterface
(远程调用不工作的接口)上向COM公开的方式的内容(所有实现的属性和其他接口),但是运气不好

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

编辑

后来我发现,如果我使用与它工作的对象相同的方法(oType.InvokeMember(“GetOtherObjForMyClassMethod”,…)检索它不工作的对象(
IOtherObjectInterface
),它仍然不工作(我对该对象的调用仍然没有转发到outproc COM服务器)

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

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

EDIT2:


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

根据Marc的回答,您需要使用ServicedComponent:


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

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

  • 您可能需要配置安全性。

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

    答案必须是
    IMyInterface.GetOtherObject()
    实例化“OtherObject”,然后当它返回时,该实例将被封送到调用进程。如果对象是可序列化的.NET类型,则默认情况下会发生这种情况

    我认为,如果对象是一个
    MarshallByRefObject
    ,它将不会被封送回调用进程:调用代码将接收一个TransparentProxy,然后对它的调用将按预期进行远程处理


    原始(
    IMyInterface
    )对象是一种特殊情况,因为调用代码本身使用激活器和从ProgID派生的类型在帮助下(在引擎盖下)实例化了它COM运行时,产生特殊的代理类型_ComObject。

    它说这是一个选项。正如我上面解释的,它只适用于一个类(不使用ServicedComponent)但不是另一个,但我无法找出使其在一种情况下工作的两种情况之间的区别…注意:我发现这不是DCOM问题,进程在同一台机器上运行。
    我认为具有此属性的类型的默认值是按值封送。
    -是的,但您没有封送此实例(它存在于OOP COM服务器进程中),您正在与CLR创建的它的
    \uuuu ComObject
    代理进行对话。正如我所说,它适用于一个类,而不适用于另一个类。因此,问题不在于承载这两个类的应用程序的配置(否则它根本不起作用)。首先,感谢您理解我的问题;-)我考虑过MarshalByRefObject,但我认为这意味着使用远程处理,我的理解是,这项技术或多或少已经过时了……我可能不得不使用该解决方案作为最后手段。嗯,
    System.\uu ComObject
    是从MarshalByRefObject派生的,所以您已经在使用它了。我想您担心您会使用一些bsolete远程处理技术是没有根据的。远程处理本身被弃用,取而代之的是WCF来实现IPC,但底层管道存在于CLR中,是COM互操作和WCF的基础。关键是我想继续使用封送处理