.Net下进程外COM服务器的实现(转)
2009-03-18 16:51
162 查看
要求:
为一个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接口。具体例子如下:
这部分和.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方法能够帮助我们很方便的实现注册和注销。
为一个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下进程外COM服务器的实现
- .Net下进程外COM服务器的实现
- COM进程外服务器实现 QueryInterface时,这样的代码为什么不行?
- 利用flash与.net下socket通信实现WEB页面的“推”(二)Flash和服务器间的通信核心:XMLSocket对象
- www.xxx.com 与 m.xxx.com 的Nginx服务器实现
- 利用excel进程实现导入功能时在本地能正常操作,在服务器上始终报错
- 并发回射服务器的具体实现及其中僵尸子进程的清理( 下 )
- 分布式 COM - IDL 续以及分布式服务器的实现
- COM+服务器的.Net组件实现 - 客户端
- 灵活正确的实现.NET插件机制开发者在线 Builder.com.cn 更新时间:2008-08-05作者: 来源:开发者在线
- 让进程外COM实现多实例
- 单台服务器的PHP进程之间实现共享内存的方法
- 用Python实现服务器中只重载被修改的进程的方法
- 阿里云服务器出现入侵事件:挖矿进程——pool.minexmr.com的解决办法
- 用 Socket 和 Pcntl 实现一个多进程服务器(一)
- 并发回射服务器的具体实现及其中僵尸子进程的清理( 上 )
- .Net中封装Windows 消息实现进程间通讯
- 网络编程(6)单进程多线程并发服务器实现
- TCP server的实现,和多线程,多进程服务器
- Linux网络编程:TCP服务器(单进程多用户),使用select方法实现