以下示例中的MyServiceStart函数是服务的入口点。MyServiceStart可以通过控制台应用程序的主要功能来访问命令行参数。第一个参数包含传递给服务的参数数。总是会有至少一个参数。第二个参数是指向字符串指针数组的指针。数组中的第一个项目总是指向服务名称。
MyServiceStart函数首先填写SERVICE_STATUS结构,包括它接受的控制代码。虽然此服务接受SERVICE_CONTROL_PAUSE和SERVICE_CONTROL_CONTINUE,但当被告知要暂停时,它并不重要。标记为SERVICE_ACCEPT_PAUSE_CONTINUE,仅供参考;如果暂停不会为您的服务增加价值,请不要支持。
MyServiceStart函数然后调用RegisterServiceCtrlHandler函数注册MyService作为服务的处理器函数并开始初始化。以下示例初始化函数MyServiceInitialization是为了说明目的而被包含的;它不执行任何初始化任务,如创建其他线程。如果您的服务的初始化执行预计需要一秒钟以上的任务,您的代码必须定期调用SetServiceStatus函数发送等待提示,并检查点,表示正在进行。
当初始化成功完成时,该示例调用SetServiceStatus,状态为SERVICE_RUNNING,服务继续工作。如果在初始化中发生错误,MyServiceStart将使用SetServiceStatus函数报告SERVICE_STOPPED并返回。
因为这个示例服务没有完成任何真正的任务,MyServiceStart只是将控制权返回给调用者。但是,您的服务应该使用此线程来完成其设计的任务。如果某个服务不需要线程来执行其工作(例如仅处理RPC请求的服务),则其ServiceMain函数应该将控制权返回给调用者。返回的函数重要,而不是调用ExitThread函数,因为返回允许清除为参数分配的内存。
要输出调试信息,MyServiceStart调用SvcDebugOut。SvcDebugOut的源代码在编写服务计划的主要功能中给出。
void MyServiceStart(DWORD argc,LPTSTR * argv)
{
DWORD status;
DWORD specificError;
MyServiceStatus.dwServiceType = SERVICE_WIN32;
MyServiceStatus.dwCurrentState = SERVICE_START_PENDING;
MyServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP |
SERVICE_ACCEPT_PAUSE_CONTINUE;
MyServiceStatus.dwWin32ExitCode = 0;
MyServiceStatus.dwServiceSpecificExitCode = 0;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;
MyServiceStatusHandle = RegisterServiceCtrlHandler(
TEXT("MyService"),
MyServiceCtrlHandler);
if (MyServiceStatusHandle == (SERVICE_STATUS_HANDLE)0)
{
SvcDebugOut(“[MY_SERVICE] RegisterServiceCtrlHandler
failed %d\n", GetLastError());
return;
}
//初始化代码到这里。
status = MyServiceInitialization(argc,argv, &specificError);
//处理错误条件
if (status != NO_ERROR)
{
MyServiceStatus.dwCurrentState = SERVICE_STOPPED;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;
MyServiceStatus.dwWin32ExitCode = status;
MyServiceStatus.dwServiceSpecificExitCode = specificError;
SetServiceStatus (MyServiceStatusHandle, &MyServiceStatus);
return;
}
//初始化完成 - 报告运行状态。
MyServiceStatus.dwCurrentState = SERVICE_RUNNING;
MyServiceStatus.dwCheckPoint = 0;
MyServiceStatus.dwWaitHint = 0;
if(!SetServiceStatus(MyServiceStatusHandle,& MyServiceStatus))
{
status = GetLastError();
SvcDebugOut(“[MY_SERVICE] SetServiceStatus错误
%ld\n",status);
}
//这是服务工作的地方。
SvcDebugOut(" [MY_SERVICE] Returning the Main Thread \n",0);
return;
}
//存根初始化函数。
DWORD MyServiceInitialization(DWORD argc,LPTSTR * argv,
DWORD * specificError)
{
argv;
argc;
specificError;
return(0);
}