玩转Windows服务系列——给Windows服务添加COM接口
当我们运行一个Windows服务的时候,一般情况下,我们会选择以非窗口或者非控制台的方式运行,这样,它就只是一个后台程序,没有界面供我们进行交互。
那么当我们想与Windows服务进行实时交互的时候,我们应该怎么做呢?
快速给Windows服务添加实时交互功能的方案
Windows服务是一个进程,而我们用于交互的程序,又是另外一个进程。我们与Windows服务实时交互,其实就是一个进程间通信的问题。所有的进程间通信的方案基本上都适用于实时交互的方案,比如Socket、共享内存、管道、COM等。
这些方案中,当属COM的开发最快速,因为我们是给基于ATL的Windows服务添加COM接口嘛。
COM简介
组件对象模型,英文为Component Object Model,缩写COM,是微软的一套软件组件的二进制接口标准。这使得跨编程语言的进程间通信、动态对象创建成为可能。COM是多项微软技术与框架的基础,包括OLE, OLE自动化, ActiveX, COM+, DCOM, Windows shell, DirectX, Windows Runtime。详细介绍可以参考 组件对象模型。
给服务添加COM接口
创建基于ATL的Windows服务可以参考 玩转Windows服务系列——创建Windows服务。
接下来,快速给服务添加COM接口。
首先给项目添加了一个ATL简单对象,如下:



按上面步骤创建了ATL简单对象后,会产生这么一个文件:
ServiceComTest.idl
文件内容如下:
import "oaidl.idl";
import "ocidl.idl"; [
object,
uuid(4DDE5CA3-F5D7-4BC3-9045-E697297C5530),
dual,
nonextensible,
pointer_default(unique)
]
interface IIServiceComTest : IDispatch{
};
[
uuid(54A347BA-7689-4578-A346-C96D924BD637),
version(1.0),
]
library ServiceComTestLib
{
importlib("stdole2.tlb");
[
uuid(C264868C-91E7-4BFE-8DD9-32D0804E44F6)
]
coclass IServiceComTest
{
[default] interface IIServiceComTest;
};
};
这个idl文件就是用来定义COM接口的。
接下来给接口添加新的方法。
在类视图中,找到刚刚生成的接口 IIServiceComTest:

然后右键菜单,添加方法:



这样,就添加了一个add方法,x、y为输入,result为输出。
然后可以在idl文件中看到add方法的定义:
interface IIServiceComTest : IDispatch{
[id(1), helpstring("两个整数相加")] HRESULT add([in] LONG x, [in] LONG y, [out, retval] LONG* result);
};
实现COM接口
我们给COM接口添加的方法,只是一个声明、描述,我们还必须实现这个方法,其他进程才能与此服务通信。
在IServiceComTest.cpp文件中可以找到此方法:
STDMETHODIMP CIServiceComTest::add(LONG x, LONG y, LONG* result)
{
// TODO: 在此添加实现代码 return S_OK;
}
接下来就是实现此方法,如下:
STDMETHODIMP CIServiceComTest::add(LONG x, LONG y, LONG* result)
{
*result = x + y;
return S_OK;
}
这样,一个完整的COM接口及其实现就算是完成了,接下来需要通过测试程序调用此接口进行测试了。
调用COM接口
创建一个基本的控制台程序,然后将初始化测试代码,进行测试,代码如下:
#include "..\ServiceComTest\ServiceComTest_i.c"
#include "..\ServiceComTest\ServiceComTest_i.h"
#include <iostream>
using namespace std; int _tmain(int argc, _TCHAR* argv[])
{
IIServiceComTest* test;
CoInitialize(NULL);
auto hresult = CoCreateInstance(CLSID_IServiceComTest,
NULL,
CLSCTX_LOCAL_SERVER | CLSCTX_INPROC_HANDLER,
IID_IIServiceComTest,
(void**)&test); LONG x = 1;
LONG y = 2;
LONG result = 0;
hresult = test->add(x, y, &result);
cout << "result is " << result << endl;
system("pause");
}
这里,只是一个演示程序,省略了代码的错误处理。
运行程序,得到了正确的结果,result is 3, 结果如下:

参考资料
COM(C++) programming tutorials
C/C++ COM Code Example: Reading Messages Asynchronously
系列链接
玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理
玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案
玩转Windows服务系列——Windows服务启动超时时间
玩转Windows服务系列——使用Boost.Application快速构建Windows服务
玩转Windows服务系列——给Windows服务添加COM接口
玩转Windows服务系列——给Windows服务添加COM接口的更多相关文章
- 玩转Windows服务系列——创建Windows服务
创建Windows服务的项目 新建项目->C++语言->ATL->ATL项目->服务(EXE) 这样就创建了一个Windows服务项目. 生成的解决方案包含两个项目:Servi ...
- 玩转Windows服务系列——创建Windows服务
原文:玩转Windows服务系列——创建Windows服务 创建Windows服务的项目 新建项目->C++语言->ATL->ATL项目->服务(EXE) 这样就创建了一个Wi ...
- Spring Cloud微服务系列文,服务调用框架Feign
之前博文的案例中,我们是通过RestTemplate来调用服务,而Feign框架则在此基础上做了一层封装,比如,可以通过注解等方式来绑定参数,或者以声明的方式来指定请求返回类型是JSON. 这种 ...
- 【转】「Chris Richardson 微服务系列」微服务架构的优势与不足
Posted on 2016年5月4日 编者的话|本文来自 Nginx 官方博客,是微服务系列文章的第一篇,主要探讨了传统的单体式应用的不足,以及微服务架构的优势与挑战. 作者介绍:Chris Ric ...
- 【CHRIS RICHARDSON 微服务系列】微服务架构中的进程间通信-3
编者的话 |本文来自 Nginx 官方博客,是微服务系列文章的第三篇,在第一篇文章中介绍了微服务架构模式,与单体模式进行了比较,并且讨论了使用微服务架构的优缺点.第二篇描述了采用微服务架构的应用客户端 ...
- 【SpringCloud构建微服务系列】微服务网关Zuul
一.为什么要用微服务网关 在微服务架构中,一般不同的微服务有不同的网络地址,而外部客户端(如手机APP)可能需要调用多个接口才能完成一次业务需求.例如一个电影购票的手机APP,可能会调用多个微服务的接 ...
- 玩转Windows服务系列——使用Boost.Application快速构建Windows服务
玩转Windows服务系列——创建Windows服务一文中,介绍了如何快速使用VS构建一个Windows服务.Debug.Release版本的注册和卸载,及其原理和服务运行.停止流程浅析分别介绍了Wi ...
- 玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理
Windows服务Debug版本 注册 Services.exe -regserver 卸载 Services.exe -unregserver Windows服务Release版本 注册 Servi ...
- 玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案
将VS创建的Windows服务项目编译生成的程序,通过命令行 “服务.exe -Service”注册为Windows服务后,就可以通过服务管理器进行管理了. 问题 通过服务管理器进行启动的时候,发现服 ...
随机推荐
- gentoo 安装
加载完光驱后 1进行ping命令查看网络是否通畅 2设置硬盘的标识为GPT(主要用于64位且启动模式为UEFI,还有一个是MBR,主要用于32位且启动模式为bois) parted -a optima ...
- 使用C#处理基于比特流的数据
使用C#处理基于比特流的数据 0x00 起因 最近需要处理一些基于比特流的数据,计算机处理数据一般都是以byte(8bit)为单位的,使用BinaryReader读取的数据也是如此,即使读取bool型 ...
- 【大型网站技术实践】初级篇:借助LVS+Keepalived实现负载均衡
一.负载均衡:必不可少的基础手段 1.1 找更多的牛来拉车吧 当前大多数的互联网系统都使用了服务器集群技术,集群即将相同服务部署在多台服务器上构成一个集群整体对外提供服务,这些集群可以是Web应用服务 ...
- 让 windows 下的命令行程序 cmd.exe 用起来更顺手
在 Windows 下使用 Larave 框架做开发,从 Composer 到 artisan 总是避免不了和 cmd.exe 打交道,系统默认的命令行界面却是不怎么好看,且每行显示的字符数是做了限制 ...
- ASP.NET MVC5+EF6+EasyUI 后台管理系统(76)-微信公众平台开发-网页授权
前言 网页授权是:应用或者网站请求你用你的微信帐号登录,同意之后第三方应用可以获取你的个人信息 网上说了一大堆参数,实际很难理解和猜透,我们以实际的代码来演示比较通俗易懂 配置 实现之前我们必须配置用 ...
- OEL上使用yum install oracle-validated 简化主机配置工作
环境:OEL 5.7 + Oracle 10.2.0.5 RAC 如果你正在用OEL(Oracle Enterprise Linux)系统部署Oracle,那么可以使用yum安装oracle-vali ...
- 异步 HttpContext.Current 为空null 另一种解决方法
1.场景 在导入通讯录过程中,把导入的失败.成功的号码数进行统计,然后保存到session中,客户端通过轮询显示状态. 在实现过程中,使用的async调用方法,出现HttpContext.Curren ...
- 三星Note 7停产,原来是吃了流程的亏
三星Note 7发售两个月即成为全球噩梦,从首炸到传言停产仅仅47天.所谓"屋漏偏逢连天雨",相比华为.小米等品牌对其全球市场的挤压.侵蚀,Galaxy Note 7爆炸事件这场连 ...
- 解决使用IE8打开ADFS 3.0登录页面
系统上线前一天,发现客户竟然有XP系统和2003系统,这些系统都不能访问外网.测试时,客户端是IE8,打开我们系统ADFS的登录页面,一直在Loading,无法打开,也不报错.后来通过fiddler跟 ...
- 一些关于Linux入侵应急响应的碎碎念
近半年做了很多应急响应项目,针对黑客入侵.但疲于没有时间来总结一些常用的东西,寄希望用这篇博文分享一些安全工程师在处理应急响应时常见的套路,因为方面众多可能有些杂碎. 个人认为入侵响应的核心无外乎四个 ...