VC++ Service编程(五)编写Control Handler函数

来源:互联网 发布:网络和ip地址计算 编辑:程序博客网 时间:2024/06/07 09:46

编写Control Handler函数

    下面例子中的MyServiceCtrlHandler函数是一个Handler函数。当被调度线程调用时,它处理Opcode参数传进来的控制码,然后调用SetServiceStatus函数更新服务的状态。Handler函数收到一个控制码后,不管做什么操作,服务都应该调用SetServiceStatus函数。
    当接收到暂停请求,MyServiceCtrlHandler将SERVICE_STATUS结构中的dwCurrentState设置为SERVICE_PAUSED。同样的,当接收到继续请求时,状态被设置为SERVICE_RUNNING。所以,对于处理暂停和继续请求,MyServiceCtrlHandler函数并不是一个好例子。因为,MyServiceCtrlHandler函数是一个Handler函数的模版,暂停和继续控制的代码并不完整。支持暂停和继续控制的服务应该用一个有意义的方法来处理这些控制。很多服务都不支持暂停或者继续控制。如果服务利用dwControlsAccepted参数来指明它不支持暂停或继续,那么,SCM(服务控制管理器)就不会向服务的Handler函数发送暂停或继续控制信息。
    为了输出调试信息,MyServiceCtrlHandler调用SvcDebugOut。SvcDebugOut的代码已经在“编写main函数”中列出。并且,注意一下,MyServiceStatus变量是一个全局变量,应该像在“编写ServiceMain函数”中描述的那样进行初始化。

#include <windows.h>

SERVICE_STATUS          MyServiceStatus; 
SERVICE_STATUS_HANDLE   MyServiceStatusHandle;

VOID SvcDebugOut(LPSTR String, DWORD Status);

VOID WINAPI MyServiceCtrlHandler (DWORD Opcode) 

   DWORD status; 
 
   switch(Opcode) 
   { 
      case SERVICE_CONTROL_PAUSE: 
      // Do whatever it takes to pause here. 
         MyServiceStatus.dwCurrentState = SERVICE_PAUSED; 
         break; 
 
      case SERVICE_CONTROL_CONTINUE: 
      // Do whatever it takes to continue here. 
         MyServiceStatus.dwCurrentState = SERVICE_RUNNING; 
         break; 
 
      case SERVICE_CONTROL_STOP: 
      // Do whatever it takes to stop here. 
         MyServiceStatus.dwWin32ExitCode = 0; 
         MyServiceStatus.dwCurrentState  = SERVICE_STOPPED; 
         MyServiceStatus.dwCheckPoint    = 0; 
         MyServiceStatus.dwWaitHint      = 0;

         if (!SetServiceStatus (MyServiceStatusHandle, 
           &MyServiceStatus))
         { 
            status = GetLastError(); 
            SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld ", 
               status); 
         } 
 
         SvcDebugOut(" [MY_SERVICE] Leaving MyService ",0); 
         return; 
 
      case SERVICE_CONTROL_INTERROGATE: 
      // Fall through to send current status. 
         break; 
 
      default: 
         SvcDebugOut(" [MY_SERVICE] Unrecognized opcode %ld ", 
             Opcode); 
   } 
 
   // Send current status. 
   if (!SetServiceStatus (MyServiceStatusHandle,  &MyServiceStatus)) 
   { 
      status = GetLastError(); 
      SvcDebugOut(" [MY_SERVICE] SetServiceStatus error %ld ", 
         status); 
   } 
   return; 
}

0 0
原创粉丝点击