服务是一种在系统中常驻的程序,服务可以在系统启动时自启动。当一个应用程序需要常驻在系统,或者随时为其他应用程序提供服务时,可以使用服务应用程序。
我们可以通过“控制面板”->“管理工具"->"服务"来查看系统中所有服务的状态。
说到服务,就要说到”服务控制器(SCM)"。服务控制器对系统中所有的服务进行管理,SCM管理着系统中已经安装的服务程序和设备驱动程序数据库,数据库中保存的信息包括系统安装了那些服务,每个服务包括如何启动每个服务、各个服务的安全属性以及控制接口等。
一个服务具有若干个属性,包括服务名称、显示名称、服务类型、描述、可执行文件路径、启动类型、服务状态、启动参数、依存关系等。我们就不多介绍了。
下面我们讲讲如何编写服务程序。
一个服务程序至少包括入口函数、服务主函数和控制处理函数。
服务主函数有两个,一个是ServiceMain函数,一个是StartServiceCtrlDispatcher函数。
控制处理函数包括两个,一个是控制处理函数Handler,一个是注册控制管理函数RegisterServiceCtrlHandler.详细的解释就请各位到百度搜一下吧。下面我写一个测试程序。大家有空就看一下。
一个控制台的服务类程序。Service.c:
#include <windows.h> //头文件
SERVICE_STATUS SplSrvServiceStaus; //全局变量
SERVICE_STATUS SplSrvServiceStatusHandle; //全局变量
//函数声明
VOID SvcDebugOut(LPSTR String,DWORD Status);
VOID WINAPI SplSrvServiceCtrlHandler(DWORD opcode);
VOID WINAPI SplSrvServiceStart(DWORD argc,LPTSTR *argv,DWORD *specificError);
//服务启动函数
VOID WINAPI SplSrvServiceStart(DWORD argc,LPTSTR *argv)
{
DWORD status;
DWORD specificError;
//填充SERVICE_STATUA结构
SplSrvServiceStatus.dwServiceType = SERVICE_WIN32;
SplSrvServiceStatus.dwCurrentState = SERVICE_START_PENDING; //服务在运行
SplSrvServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_PAUSE_CONTINUE;
SplSrvServiceStatus.dwWin32ExitCode = 0;
SplSrvServiceStatus.dwServiceSpecificExitCode = 0;
SplSrvServiceStatus.dwCheckPoint = 0;
SplSrvServiceStatus.dwWaitHint = 0;
//注册服务控制请求处理列程
SplSrvServiceStatusHandle = RegisterServiceCtrlHandle("Sample_Srv" //服务名
,SplSrvServiceCtrlHandle);//函数名
if(SplSrvServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
SvcDebugOut(" [SPLSRV_SERVICE] RegisterServiceCtrlHandler failed %d\n",GetLastError());
return ;
}
//初始化工作,本示例未用,函数为空
status = SplSrvServiceInitialization(argc,argv,&specificError);
//初始化出错,用户自行修改
if(status != NO_ERROR)
{
SplSrvServiceStatus.dwCurrentState = SERVICE_STOPPED;
SplSrvServiceStatus.dwCheckPoint = 0;
SplSrvServiceStatus.dwWaitHint = 0;
SplSrvServiceStatus.dwWin32ExitCode = status;
SplSrvServiceStaus.dwServiceSpecificExitCode = specificError;
SetServiceStatus(SplSrvServiceStatusHandle,&SplSrvServiceStatus);
return ;
}
//初始化完成,设置运行状态
SplSrvServiceStatus.dwCurrentState = SERVICE_RUNNING;
SplSrvServiceStatus.dwCheckPoint = 0;
SplSrvServiceStatus.dwWaitHint = 0;
if(!SetServiceStatus(SplSrvServiceStatusHandle,&SplSrvServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [SPLSRV_SERVICE] SetServiceStatus error %ld\n",status);
}
//用户自行修改,用于完成服务的工作
SvcDebug(" [SPLSRV_SERVICE] Returning the Main Thread \n",0);
return ;
}
//初始化函数
DWORD SplSrvServiceInitialization(DWORD argc,LPTSTR *argv,DWORD specificError)
{
return 0;
}
//服务器请求处理函数
VOID WINAPI SplSrvServiceCtrlHandle(DWORD Opcode)
{
DWORD status;
switch(Opcode)
{
case SERVICE_CONTROL_PAUSE:
//完成相关功能
SplSrvServiceStatus.dwCurrentState = SERVICE_PAUSED;
break;
case SERVICE_CONTROL_CONTINUE:
//完成相关功能
SplSrvServiceStatus.dwCurrentState = SERVICE_RUNNING;
break;
case SERVICE_CONTROL_STOP:
//完成相关功能
SplSrvServiceStatus.dwWin32ExitCode = 0;
SplSrvServiceStatus.dwCurrentState = SERVICE_STOPPED;
SplSrvServiceStatus.dwCheckPoint =0;
SplSrvServiceStatus.dwWaitHint = 0;
if(!SetServiceStatus(SplSrvServiceStatusHandle,&SplSrvServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [SPLSRV_SERVICE] SetServiceStatus error %ld\n",status);
}
SvcDebugout(" [SPLSRV_SERVICE] Leaving SplSrvService \n",0);
return ;
case SERVICE_CONTROL_INTERROGATE:
//收到此请求后复出声响,演示服务控制请求的处理过程,
MessageBox(MB_OK);
break;
default:
SvcDebugout(" [SPLSRV_SERVICE] Unrecognized opcode %ld\n",Opcode);
}
//当前状态
if(!SetServiceStatus(SplSrvServiceStatusHandle,&SplSrvServiceStatus))
{
status = GetLastError();
SvcDebugOut(" [SPLSRV_SERVICE] SetServiceStatus error %ld\n",status);
}
return ;
}
//程序入口函数
void main()
{
//设置SERVICE_TABLE_ENTRY数据结构,以NULL结构结束
//作为StartServiceCtrlDispatcher函数的参数
SERVICE_TABLE_ENTRY DispatchTable[] =
{
{ "Sample_Srv",(LPSERVICE_MAIN_FUNCTION) SplSrvServiceStart },
{ NULL,NULL }
};
if(!StartServiceCtrlDispatcher(DispatchTable))
{
SvcDebugOut(" [SPLSRV_SERVICE] StartServiceCtrlDispatcher (%d)\n",GetLastError());
}
}
//显示信息给调试器
VOID SvcEgbugOut(LPSTR Stringm,DWORD Status)
{
CHAR Buffer[1024];
if(strlen(String) < 1000)
{
wsprintf(Buffer,String,Status);
OutputdebugString(Buffer);
}
}