首页 | 互联网 | IT动态 | IT培训 | Cisco | Windows | Linux | Java | .Net | Oracle | 软件测试 | C/C++ | 嵌入式开发 | 存储世界 | 服务器
网络设备 | IDC | 安全 | 求职招聘 | 数字网校 | 网页设计 | 平面设计 | 技术专题 | 电子书下载 | 教学视频 | 源码下载 | 搜索 | 博客 | 论坛
中国IT实验室Dotnet频道
中国IT教育
Google
首页 ASP.NET  C#  XML/WebService ADO.NET VC.NET VB.NET .NET 资讯动态 专题 RSS订阅 讨论 下载
您现在的位置: 中国IT实验室 >> Dotnet >> VC.NET >> 正文

.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);
}
 

对于.Net 2.0之前的情况,我们可以通过下面的方式使用.Net自己的IClassFactory实现来实现SCM的注册

[1] [2] [3] 下一页

【责编:Peng】

中国IT教育

相关产品和培训
文章评论
 友情推荐链接
 认证培训
 专题推荐

 ·关于Java框架技术专题
 ·XML全攻略技术专题
 ·JAVA开源技术介绍专题
 ·Java嵌入式开发之J2ME技术专题
 ·超前体验 Oracle 11g的5个新特性…
 ·揭密使用VB.NET的五个实用技巧
 ·Oracle和SQL Server常用函数对比专题…
 ·展现C#世界 C#程序设计专题…
 ·Java入门 Tomcat的配置技巧精华专题…
 ·Oracle RMAN物理备份技术详解…
 今日更新
 社区讨论
 博客论点
 频道精选
 Dotnet频道相关导航