Windows Service是一种在后台运行的程序,它没有与用户交互的界面操作.
Windows Service属于控制台程序,下面将对Service编程做一个简要的介绍:
1.包含头文件
#include<stdio.h> 日志写入磁盘
2.输入日志路径
#define SERVICE_LOG_FILE ("D:\\feAudioService\\AudioService\\log.txt")
3.静态全局变量
static SERVICE_STATUS ServiceStatus;
static SERVICE_STATUS_HANDLE hStatus;
static FILE* log;
现在可以编码了,服务程序控制台程序的一个子集。因此,需要定义 main 函数,它是程序的入口点。
4.控制台程序入口
void main(int argc, const char **argv)
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "PlayAudioService";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
}
5.服务入口点
void ServiceMain(int argc, const char **argv){}
在服务入口里面,需要设置服务入口的参数和注册命令控制器、打开和写入日志,以及报告服务运行状态。
5.1 设置服务入口参数和注册控制命令
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler( "PlayAudioService", (LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return ;
}
dwServiceType:指示服务类型,创建 Win32 服务。赋值 SERVICE_WIN32;
dwCurrentState:指定服务的当前状态。因为服务的初始化在这里没有完成,所以这里的状态为 SERVICE_START_PENDING;
dwControlsAccepted:这个域通知 SCM 服务接受哪个域。本文例子是允许 STOP 和 SHUTDOWN 请求。处理控制请求将在第三步讨论;
dwWin32ExitCode 和 dwServiceSpecificExitCode:这两个域在你终止服务并报告退出细节时很有用。初始化服务时并不退出,因此,它们的值为 0;
dwCheckPoint 和 dwWaitHint:这两个域表示初始化某个服务进程时要30秒以上。本文例子服务的初始化过程很短,所以这两个域的值都为 0。
ServiceMain 应该尽可能早早为服务注册控制处理器。这要通过调用 RegisterServiceCtrlHadler 函数来实现。你要将两个参数传递给此函数:
服务名和指向ControlHandlerfunction 的指针。
5.2 日志相关操作
void OpenLog()
{
log = fopen(SERVICE_LOG_FILE, "a+");
}
void WriteToLog(char* str)
{
OpenLog();
fprintf(log, "%s\n", str);
CloseLog();
}
void CloseLog()
{
fclose(log);
}
5.3 报告服务运行状态
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);
注册完控制处理器之后,获得状态句柄(hStatus);通过调用 SetServiceStatus 函数,用 hStatus 向 SCM 报告服务的状态。
6.命令控制器
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Service Stop Exiting\n");
done = 1;
Mux_ExitMuxApp();
WriteToLog("Service Stop Exit OK\n");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Service Shutdown Exiting\n");
done = 1;
Mux_ExitMuxApp();
WriteToLog("Service Shutdown Exit OK\n");
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus (hStatus, &ServiceStatus);
}
7.异常处理
void ServiceError(void)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
}
8.安装和卸载
在DOS下输入命令:
安装: sc create PlayAudioService binPath= D:\feAudioService\AudioService\Debug\AudioService.exe
卸载: sc delete PlayAudioService
相关文章:http://blog.chinaunix.net/u1/51827/showart_1986489.html