编写一个ServiceMain函数

【勇芳软件工作室】汉化Home

以下示例中的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);

}