玩转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, 结果如下:

参考资料

Step by Step COM Tutorial

COM in C++

COM(C++) programming tutorials

C/C++ COM Code Example: Reading Messages Asynchronously

系列链接

玩转Windows服务系列——创建Windows服务

玩转Windows服务系列——Debug、Release版本的注册和卸载,及其原理

玩转Windows服务系列——无COM接口Windows服务启动失败原因及解决方案

玩转Windows服务系列——服务运行、停止流程浅析

玩转Windows服务系列——Windows服务小技巧

玩转Windows服务系列——命令行管理Windows服务

玩转Windows服务系列——Windows服务启动超时时间

玩转Windows服务系列——使用Boost.Application快速构建Windows服务

玩转Windows服务系列——给Windows服务添加COM接口

时间: 2024-08-01 10:46:38

玩转Windows服务系列——给Windows服务添加COM接口的相关文章

[转]玩转Windows服务系列——命令行管理Windows服务

本文转自:http://www.cnblogs.com/hbccdf/p/managewindowsservicewithcmd.html 说到Windows服务的管理就不得不说通过命令行的方式管理Windows服务,因为无论是系统管理员,还是通过编程的方式调用cmd命令,命令行都是非常方便以及强大的工具. 接下来就看一下如何通过cmd命令管理Windows服务. 管理Windows服务的主要cmd命令 管理Windows服务的命令应该有很多,但是我所了解到的命令主要有两个:sc.net. 说是

玩转Windows服务系列&mdash;&mdash;Windows服务启动超时时间

最近有客户反映,机房出现断电情况,服务器的系统重新启动后,数据库服务自启动失败.第一次遇到这种情况,为了查看是不是断电情况导致数据库文件损坏,从客户的服务器拿到数据库的日志,进行分析. 数据库工作机制 要分析数据库启动失败的原因,首先说明一下数据库服务的工作机制. 数据库分为六大服务: 数据库的六大服务之间存在依赖关系,及启动流程: 服务自动启动失败原因 从客户那里,拿到了两份日志,一份是开机自启动的日志信息,此次数据库启动失败.另外一份是开机后,手动启动数据库服务的日志信息,此次数据库启动成功

玩转Windows服务系列汇总(9篇文章)

玩转Windows服务系列汇总 创建Windows服务Debug.Release版本的注册和卸载及其原理无COM接口Windows服务启动失败原因及解决方案服务运行.停止流程浅析Windows服务小技巧命令行管理Windows服务Windows服务启动超时时间使用Boost.Application快速构建Windows服务给Windows服务添加COM接口 http://www.cnblogs.com/hbccdf/p/summary_of_windows_service.html

C#制作Windows service服务系列二:演示一个定期执行的windows服务及调试(windows service)

系列一: 制作一个可安装.可启动.可停止.可卸载的Windows service(downmoon原创) 系列二:演示一个定期执行的windows服务及调试(windows service)(downmoon) 系列三: windows service系列三--制作可控制界面的windows service 一.经常有人问起如何让程序定期自动执行? 除了像系统任务和SQL JOB/DTS等都可以满足不同的用户需求外,这里演示了如何做一个简单的windows serivce的框架.主要的功能是按照

Windows Server 2012配置L2TP服务环境

在上一篇文章<Windows Server 2012配置VPN服务环境>中讲解了在Windows Server2012环境中的基础VPN搭建,但是只能支持PPTP的VPN连接.这篇文章进一步完善了VPN基于L2TP的连接讲解. 在百度上也没有找到一个Windows2012 很全的L2TP服务搭建的方案,所以自己编辑了一个给有需要的朋友们参考. 准备环境:Windows Server 2012R2 数据中心版64位,基础的VPN服务环境已经搭建完成. 功能需求:完善VPN服务器来支持L2TP类型

交通银行 Java Socket 服务启动 管理 WINDOWS 版

按照交通银行提供的无界面启动方法试验了很多次,都没有成功,所以自己动手用C# 知识写了一个. 小工具可以判断 交通银行 JAVA SOCKET 服务是否启动,并可以启动/关闭服务 主要代码如下: 判断服务是否启动 引用 :using System.Management; SelectQuery selectQuery = new SelectQuery(“select * from Win32_Process where Name = ‘java.exe’”); object cmdLine =

Windows服务二:测试新建的服务、调试Windows服务

一.测试Windows服务 为了使Windows服务程序能够正常运行,我们需要像创建一般应用程序那样为它创建一个程序的入口点.像其他应用程序一样,Windows服务也是在Program.cs的Main()函数中完成这个操作.首先我们在Main()函数中创建一个Windows服务的实例,该实例应该是ServiceBase类的某个子类的对象,然后我们调用由基类ServiceBase类定义的一个Run()方法.然而调用Run()方法并不意味着就开始了Windows服务程序,必须要等到该对象的OnSta

Windows azure中公用云服务的两个虚机FTP的设置

在Windows azure中,若两个虚机公用一个云服务,则这两个虚机对互联网的IP即外网的IP是一样. 建立FTP的时候,在此处选择指定的用户,在两个虚机里要设置不同FTP用户的账户,并同时在FTP目录中添加对应的FTP账户!     这样在通过FTP链接的时候,输入相同的IP和不同的账号,则会连接到账号对应的虚机 Windows azure中公用云服务的两个虚机FTP的设置,布布扣,bubuko.com

wcf Rest 服务宿主在windows服务及客户端访问

首先写好服务,代码如下: 1 using System; 2 using System.Collections.Generic; 3 using System.Runtime.Serialization; 4 using System.ServiceModel.Web; 5 using System.ServiceModel; 6 7 8 namespace Artech.WcfServices.Service 9 { 10 [ServiceContract(Namespace = "Artec