预备知识
- COM组件
- 进程
- VC++
- Windows
- DLL
- 管道
- JSON
- 参考文章 https://www.cnblogs.com/baiyanhuang/archive/2009/11/22/1730724.html
获得的知识
- 客户端进程通过代理(Proxy)与服务器端进程通过(Stub)进行跨进程调用
- 管道服务器与客户端的通信
前言
具备预备知识的童鞋应该知道所谓COM组件的无差别调用是建立在注册表的基础上的,在要使用一个COM组件之前,先注册这个组件的DLL(EXE)到注册表,当某个客户端使用这个COM接口时,系统会去注册表查这个接口所在的DLL(EXE)的存放路径,然后把它Load起来(EXE则跑起来),然后你就可以调这个接口了,这样我们就可以获得许多别人写的库里实现的功能而不需要关心实现了,很神奇对不对。
一、组件如何被调用的
- 查询注册表,得到组件路径
- 通过导出接口DllGetClassObject得到类厂IClassFactory
- 使用CoRegisterClassObject把类厂注册到全局运行对象表(RunningObjectTable/ROT)
- 客户端通过CoGetClassObject获得对应的类厂
- 用IClassFactory->CreateInstance/CoCreateInstance获得接口
- 调用相应功能
二、没有注册权限怎么办
- 服务器端
- LoadLibrary载入提供实现的DLL
- 通过导出接口DllGetClassObject得到类厂IClassFactory
- 使用CoRegisterClassObject把类厂注册到全局运行对象表(RunningObjectTable/ROT)
- 使用消息泵(GetMessage)
- 客户端
- 或注册接口的tlb文件到注册表,原程序无需修改
- 或使用系统注册表已经提供了的接口替换原接口,原程序需修改
如:原来可以注册到系统时
// 接口实现
interface IMyInterface:public IDispatch
...
{
STDMETHOD(Do)(void);
...
}
// 客户端使用
CComQIPtr<IMyInterface> spMyInt;
spMyInt.CoCreateInstance(CLSID_MyInterface);
spMyInt->Do();
...
不能使用注册表时
// 接口实现
interface IMyInterface:public IDispatch
...
{
STDMETHOD(Do)(void);
...
}
// 客户端使用
CComQIPtr<IDispatch> spMyInt;
spMyInt.CoCreateInstance(CLSID_MyInterface);
spMyInt.Invoke0(L"Do", NULL, NULL);
...
注意:这种服务器/客户端的调用只能是相同权限的,即服务器如果是Administrator,客户端也要是Administrator.
! 会弹UAC框
三、要安静一点,客户端没有UAC,跨权限
参考文章 https://baike.baidu.com/item/Proxy%20Stub/3088651?fr=aladdin
文章的最后一部分写到
对于你来说代理和存根的使用是透明的,你根本不用去关心如何使用他们,com库会知道怎么做。
Excuse me?
我们自己来吧
- 实现Proxy/Stub,VS IDE在生成ATL Simple Object 的时候就自动给我们生成了两个工程,一个是实现接口的工程,另一个是Marshal接口的Proxy DLL
- 实现服务器与客户端的通信,这里使用管道的方式
实现接口DLL自注册到自定义管理文件
运行过程
服务器端
- 启动管道服务器进行侦听
- 从代理DLL的IPSFactoryBuffer接口得到IRpcStubBuffer接口
- 客户端数据进入时,分析数据用特定的clsid和iid与
IRpcStubBuffer
进行绑定 - 调用
IRpcStubBuffer->Invoke(RPCOLEMESSAGE *...)
- 返回的
RPCOLEMESSAGE
数据返回给客户端
客户端
- 从代理DLL的
IPSFactoryBuffer
接口创建代理对象IPSFactoryBuffer->CreateProxy
,拿到要使用的接口 - 调用
IRpcProxyBuffer->connect
与管道服务器进行连接 - 通过要使用的接口进行业务调用
- 从代理DLL的
通过管道技术是可以跨机器的(Win10除外)
准备告别DCOM了吗?
最后附上代码:
http://download.youkuaiyun.com/download/flyback/10109682