畅思笔录

 

Windows Service

  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

posted on 2010-03-24 13:37  畅思笔录  阅读(951)  评论(0编辑  收藏  举报

导航