.Net下进程外COM服务器的实现(转)

要求: 
  为一个WinForm程序暴露一个COM接口,让其它应用程序能够以COM服务器(LocalServer)方式启动这个程序并且对其进行操作 
  如果发现已经在运行的应用程序,则直接重用当前运行的应用程序进行操作。 

  分析: 
  根据要求,分解具体需要解决的技术问题如下: 
  在WinForm程序中定义一个COM visible接口并实现。 
  将这个Winform程序变为COM服务器(LocalServer)。 
  将Winform程序的COM对象加入系统的ROT表中。 

  验证方法: 
  客户端通过CoCreateInstance(LocalServer)方式激活这个COM对象,应当看到对应的WinForm程序启动,并且CoCreateInstance成功返回我们所需的Interface指针, 
  客户端调用Interface的相关方法,Winform程序能够成功执行。 
  Winform程序运行时,客户端能够在ROT取得Winform程序的IUnknown指针。能够成功QI 成所实现的COM接口,并且调用相关方法成功执行。 

  解决方案: 
  1. 在WinForm程序中定义一个COM visible接口并实现 
  在. Net中定义COM 接口可以通过在接口定义上添加GuidAttribute和InterfaceTypeAttribute,定义该接口的IID并告知CLR该接口需要同时导出为普通的IUnknown COM 接口和OLE automation接口。具体例子如下:
 
 
[InterfaceType(ComInterfaceType.InterfaceIsDual)] [Guid( " CF7C704A-6AC3-4963-8818-EF1493CEC2D1 " )] public interface IProvider { void Test(); } 实现这个interface, [ClassInterface(ClassInterfaceType.None)] [Guid( " 58C142C7-E599-4921-BF29-33DC0FCCBECA " )] public class ProviderImp : IProvider { public void Test() { System.Diagnostics.Debug.WriteLine( " Test " ); } }
  这部分和.Net中实现进程内COM服务器是相同的,在.Net Framework SDK的文档中有详细的介绍。关于在.Net中实现COM组件可以参看MSDN。 

  2. 将这个Winform程序变为COM服务器(LocalServer) 
  根据COM本质论中的论述实现进程外COM服务器的需要以下几方面条件; 
  注册表中对应的CLSID下需要添加LocalServer32键,并把default设为EXE程序的路径 
  进程外服务器需要在启动时主动向SCM(Service Control Manager)中注册COM Class Object,这样SCM才能创建出对应的COM object返回给客户端,因此.Net程序需要提供一个Class Object(一个实现了IClassFactory COM接口的对象)并调用CoRegisterClassObject将其注册到SCM中。 
  除此之外,.Net中需要使用regasm命令将assembly中的COM visible类型加入注册表。(注意如果assembly没有加入GAC,请在注册的时候加上/codebase参数否则.Net会无法加载对应的 assembly产生奇怪的E_NOINTERFACE错误) 

  具体的实现方式根据使用的.Net版本有所差异:对于.Net v2.0及其后版本而言,.Net RegistrationServices类提供了RegisterTypeForComClients和 UnregisterTypeForComClients方法能够帮助我们很方便的实现注册和注销。 
 
 
private static int cookie; private static RegistrationServices msRegSvc = new RegistrationServices(); public static void RegisterServer() { Guid clsid = typeof (ProviderImp).GUID; cookie = msRegSvc.RegisterTypeForComClients( typeof (ProviderImp), RegistrationClassContext.LocalServer,RegistrationConnectionType.SingleUse); } public static void UnregisterServer() { msRegSvc.UnregisterTypeForComClients(cookie); }

转载于:https://www.cnblogs.com/devilmsg/archive/2009/03/18/1415633.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值