通过 C# 访问远程 COM 对象
Posted
技术标签:
【中文标题】通过 C# 访问远程 COM 对象【英文标题】:Accessing a remote COM object via C# 【发布时间】:2011-07-01 10:47:52 【问题描述】:我有一个使用非托管 C++ 编写的 exe 文件,其中包含一个 COM 对象。为了从托管的 C# 应用程序访问它,我生成了一个互操作程序集。当两个应用程序在同一台 PC 上运行时,我能够非常成功地使用它。
现在,我需要让我的 C# 应用程序访问远程 PC 上的 COM 对象,而现有代码给我带来了一些问题。我不得不做一些小的改变,例如
Type ReportItemSetup = Type.GetTypeFromProgID("ACME.REPORTITEMSETUP.1", remotePCName);
RpiSetup = (IReportItemSetup)Activator.CreateInstance(ReportItemSetup);
成为
Guid gris = new Guid("147FF3D1-8A00-11F0-9A6C-0000C099D00B");
Type ReportItemSetup = Type.GetTypeFromCLSID(gris, remotePCName, true);
RpiSetup = (IReportItemSetup)Activator.CreateInstance(ReportItemSetup);
这使我能够更深入地了解代码,但后来我遇到了另一个问题。
我用:
REPORTITEMSETUPClass rpis = new REPORTITEMSETUPClass();
REPORTITEMSETUPClass 所在的位置(为简洁起见进行了编辑)
namespace Acme.ReportItemServers.Interop
[ClassInterface(ClassInterfaceType.None)]
[TypeLibType(TypeLibTypeFlags.FAppObject | TypeLibTypeFlags.FCanCreate | TypeLibTypeFlags.FPreDeclId)]
[ComConversionLoss]
[Guid("147FF3D1-8A00-11F0-9A6C-0000C099D00B")]
public class REPORTITEMSETUPClass : IReportItemSetup, REPORTITEMSETUP, INotifySrc
public REPORTITEMSETUPClass();
... snip ...
public virtual void INotifySrc_AddUser(INotify pNotify, string bstrUserName);
... snip ...
我需要在 INotifySrc 接口上调用 AddUser,但 new 调用给了我错误:
Retrieving the COM class factory for component with CLSID 147FF3D1-8A00-11F0-9A6C-0000C099D00B failed due to the following error:
80040154 Class not registered (Exception from HRESULT: 0x80040154 (REGDB_E_CLASSNOTREG)).
这个错误是完全正确的,因为它没有在本地机器上注册。
因此,我的问题是:不能在远程 PC 上使用注册吗? Activator.CreateInstance 没有在本地注册类没有问题。
【问题讨论】:
【参考方案1】:我认为您必须编写一个服务组件来执行此操作。这涉及到一些 COM+ 魔法并且可能相当复杂。在这里查看摘要:http://msdn.microsoft.com/en-us/library/3x7357ez%28v=vs.71%29.aspx
【讨论】:
谢谢。我会进一步研究。【参考方案2】:创建 System.EnterpriseServices.ServicedComponent 的子类,然后在服务器的 COM+ 中安装它,然后从服务器导出一个 COM+ 代理 (msi),并在客户端安装此代理。
【讨论】:
以上是关于通过 C# 访问远程 COM 对象的主要内容,如果未能解决你的问题,请参考以下文章