zoukankan      html  css  js  c++  java
  • 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

  • 相关阅读:
    并发编程(十)—— Java 并发队列 BlockingQueue 实现之 SynchronousQueue源码分析
    并发编程(九)—— Java 并发队列 BlockingQueue 实现之 LinkedBlockingQueue 源码分析
    Java工程师成神之路
    并发编程(八)—— Java 并发队列 BlockingQueue 实现之 ArrayBlockingQueue 源码分析
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
    星空雅梦
  • 原文地址:https://www.cnblogs.com/xiehy/p/1693694.html
Copyright © 2011-2022 走看看