王朝网络
分享
 
 
 

用 ATL 编写 Windows 服务

王朝vc·作者佚名  2006-01-17
宽屏版  字体: |||超大  

用 ATL 编写 Windows 服务

作者:Alon

下载源代码

有时候,我们需要自己写的程序在没有用户登陆的情况下,只要Windows系统启动就运行,那我们可以把我们的程序写成一个Windows服务。

服务是能够为各种用户(包括本地用户和远程用户)所用的,拥有用户授权级进行管理的能力,并且不论用户是否物理的与正在运行该应用程序的计算机相连都能正常执行。

下面,我将用一个简单的例子说明如何用ATL来编写Windows服务程序。

首先,我们新建一个Project。如图一所示,选择 "ATL COM AppWizard",工程名为:ServiceDemo。

图一

点击 "OK ", 出现图二,选择Service [EXE]。点击 Finish。

图二

完成以上的步骤,一个"什么也不做"的服务就完成了!编译… 打开"控制面板"->"管理工具"

->"服务",嗯?我们写的服务怎么没有在服务管理器(service control manager ,简称(SCM))里面列出来呢?呵呵,被我骗了?不要着急,我们还需要做一些工作。

首先先大概介绍一下向导为我们生成的代码:

程序的进入点是全局函数_tWinMain, 仔细看一下这个函数,我们会发现当我们运行程序时,可以加上参数,例如: ServiceDemo /RegServer

或者 ServiceDemo -RegServer,这个是用来本地服务器注册(Register as Local S Register as

Service erver); ServiceDemo / Service 或者 ServiceDemo

-Service,这个是服务的注册(Register as Service);ServiceDemo /UnRegServer 或者

ServiceDemo -UnRegServer ,这个是服务的删除。所以,当我们写好了服务程序,只要运行的时候加上参数 Service

,这个时候在SCM中就会看到我们的服务了。可以试一下在SCM中对这个什么也不做的服务"启动","停止",改变一下它的启动方式。

每次编码后测试都要在命令行中加参数运行服务才可以在SCM中列出来是不是很麻烦呢?我再介绍一个偷懒的方法,选择VC IDE的菜单Project

-> Setting, 再选择Custom Build面板,如图三:

图三

在"$(TargetPath)" /RegServer的下面加上:"$(TargetPath)"

/Service,这样当我们每次编码后编译程序,就不用再在命令行中去加参数执行我们的服务程序完成服务的注册了。

继续介绍向导生成的代码:向导为我们建立了一个类:CServiceModule,全局变量_Module就是这个类的实例。

Init():这个函数用于完成一些初始化工作;

Run():这个函数就是服务开始运行后的内容,我们接下来要修改的内容也就是从这里入手。

Install():

看一下Install()的这一部分:

SC_HANDLE hService = ::CreateService(hSCM,

m_szServiceName,

m_szServiceName,SERVICE_ALL_ACCESS,

SERVICE_WIN32_OWN_PROCESS,

SERVICE_DEMAND_START,

SERVICE_ERROR_NORMAL,

szFilePath,

NULL,

NULL,

_T("RPCSS\0"),

NULL,

NULL);

函数的原型如下:

SC_HANDLE CreateService(

SC_HANDLE hSCManager, // handle to SCM database

LPCTSTR lpServiceName, // name of service to start

LPCTSTR lpDisplayName, // display name

DWORD dwDesiredAccess, // type of access to service

DWORD dwServiceType, // type of service

DWORD dwStartType, // when to start service

DWORD dwErrorControl, // severity of service failure

LPCTSTR lpBinaryPathName, // name of binary file

LPCTSTR lpLoadOrderGroup, // name of load ordering group

LPDWORD lpdwTagId, // tag identifier

LPCTSTR lpDependencies, // array of dependency names

LPCTSTR lpServiceStartName, // account name

LPCTSTR lpPassword // account password

);

具体的细节可以查一下MSDN,我只说一下第六个和第十一个参数。第六个参数是服务的启动类型。

SERVICE_DEMAND_START是手动启动,SERVICE_AUTO_START是自动启动。第十一个参数是服务的依存关系,比如说服务的启动想要依存SQL

Server的启动,那我们可以把这个参数写成:_T("MSSQLSERVER\0");

如果我们写的服务不依存于其他的任何服务,那我们就将此参数设置为NULL就可以了。

接下来,我们为上面的"什么也不做"的服务添加一个简单的功能:做数字的累加,并且把结果写到系统的"应用程序日志"中去。

首先,我们在类CServiceModule中添加一个成员变量:int n; 在Init()中对n进行初始化:

n = 0;

然后在类CServiceModule中添加一个成员函数Adder():

void CServiceModule::Adder()

{

n ++;

CString str;

str.Format("%i",n);

LogEvent(str);

}

编译…出错了。??,提示 CString 没有定义,难道在ATL中无法用 MFC 吗?让我们看看设置:菜单Project-Setting ,General面板,默认的设置是:Use MFC in a Static Library。那为什么不可以用MFC中的类呢?原来是头文件没有包含,这个不知道算不算 VC 的一个 Bug : ,设置中默认是用MFC,可是却没有包含相应的头文件。那我们就自己加上好了。在StdAfx.h中加上:#include ,注意要加到#include 的前面,要不然又要编译出错了。接下来,我们在程序中再添加一个Timer,让这个Timer每两秒钟调用一次Adder,做一次累加。在:MSG msg;while (GetMessage(&msg, 0, 0, 0))DispatchMessage(&msg);的前面加上代码:SetTimer(NULL,1,2000,(TIMERPROC)OnTimerProc); 注意一定要加在前面,因为要是加到while循环的下面,就没有机会执行了。再添加一个全局的回调函数OnTimerProc 如下:VOID CALLBACK OnTimerProc(HWND hwnd,UINT uMsg,UINT_PTR idEvent,DWORD dwTime){_Module.Adder();} 好了,大功告成。编译,然后在SCM中启动我们的服务。在控制面板中打开"事件查看器",看一下运行的结果,如下图四:

图四 好了,就写到这里吧,其他的内容大家自己深究吧。祝各位编程愉快!

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
>>返回首页<<
推荐阅读
 
 
频道精选
静静地坐在废墟上,四周的荒凉一望无际,忽然觉得,凄凉也很美
© 2005- 王朝网络 版权所有