Posted on 2008-07-04 23:17
阿呆 阅读(854)
评论(0) 编辑 收藏 引用
一个windows服务程序大体可以三步来写,其大体框架如下:
1
// TestService.cpp : Defines the entry point for the console application.
2
//
3![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
4
#include "stdafx.h"
5
#include <Windows.h>
6![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
7
LPTSTR g_ServiceName = _T("TestService");
8![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
9
void WINAPI ServiceCtrlHandler(DWORD code)
10![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
11
//process control requests.
12
//比如,当收到SERVICE_CONTROL_STOP请求时,设置server状态为stop
13
}
14![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
15
void MyServiceTestFuncion()
16![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
17
//service功能函数。在这里写我们要service做什么事情
18
}
19![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
20
//服务入口函数,一些初始化动作在此处进行
21
void WINAPI ServiceMain()
22![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
23
SERVICE_STATUS_HANDLE hStatus;
24
hStatus = RegisterServiceCtrlHandler(
25
g_ServiceName, //服务名称
26
ServiceCtrlHandler);//处理服务控制请求的函数
27
if (!hStatus)
28![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
29
//注册失败
30
}
31
else
32![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{
33
MyServiceTestFuncion();
34
}
35
}
36![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
37
//函数入口函数
38
int _tmain(int argc, _TCHAR* argv[])
39![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
![](http://www.cppblog.com/Images/OutliningIndicators/ContractedBlock.gif)
{
40![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
SERVICE_TABLE_ENTRY ServiceTable[] =
{
41![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{g_ServiceName, (LPSERVICE_MAIN_FUNCTIONW)ServiceMain},
42![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{NULL, NULL}
43
};
44![](http://www.cppblog.com/Images/OutliningIndicators/InBlock.gif)
45
StartServiceCtrlDispatcher(ServiceTable);
46
return 0;
47
}
48![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
49![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
以下介绍这3个步骤:
1、在main函数中调用StartServiceCtrlDispatcher函数,该函数会启动新线程来执行程序中所要执行的服务。
1![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedBlockStart.gif)
SERVICE_TABLE_ENTRY ServiceTable[] =
{
2![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{g_ServiceName, (LPSERVICE_MAIN_FUNCTIONW)ServiceMain},
3![](http://www.cppblog.com/Images/OutliningIndicators/ExpandedSubBlockStart.gif)
{NULL, NULL}
4
};
5![](http://www.cppblog.com/Images/OutliningIndicators/None.gif)
6
StartServiceCtrlDispatcher(ServiceTable);
其中,SERVICE_TABLE_ENTRY是一个结构,其中包括两个域:
LPTSTR lpServiceName;
LPSERVICE_MAIN_FUNCTION lpServiceProc;
lpServiceName指定在service进程中运行的服务的名字,它可以是空字符串("”),但不能是NULL。
我们在程序的开始处指定如下:LPTSTR g_ServiceName = _T("TestService");
lpServiceProc指向服务入口函数的指针,即新启动的服务线程的指针。
一个服务程序可以启动几个线程,取决于ServiceTable中元素的个数。注意,ServiceTable的最后一个元素必须是{NULL, NULL},以表示结束。
StartServiceCtrlDispatcher函数(其后所用的windowsAPI也是)的头文件是Windows.h,因此要包含该头文件
2、定义服务的入口函数ServiceMain。
在ServiceMain函数中调用RegisterServiceCtrlHandler函数来注册一个函数处理服务控制请求。函数调用方式如下:
RegisterServiceCtrlHandler(
g_ServiceName, //服务名称
ServiceCtrlHandler);//处理服务控制请求的函数
RegisterServiceCtrlHandler 函数返回一个SERVICE_STATUS_HANDLE类型的handle来表明service的状态,如果是0,则表示注册失败。
然后调用我们的服务最主要的函数实现我们所要实现的功能:
MyServiceTestFuncion();//实现该服务要实现的功能
3、实现ServiceCtrlHandler函数
ServiceCtrlHandler函数的定义如下:
VOID WINAPI ServiceCtrlHandler (
DWORD fdwControl
);
其中,fdwControl是Control Code,监控服务的状态,可以在其中针对服务的各种状态进行动作,比如,当fdwControl是SERVICE_CONTROL_STOP时,停止该服务。
一个service程序实现的大致步骤如上。