• WIN32编程用Windows API实现Windows NT服务的程序框架


    //点击此处下载源码

    #include <windows.h>
    #include <stdio.h>

    //变量声明
    char ServiceName[]="NTService";
    SERVICE_STATUS ssStatus;
    SERVICE_STATUS_HANDLE ServiceStatusHandle;

    //前向声明
    void ShowHelp();
    void InsallService();
    void RemoveService();
    void WINAPI ServiceMain(DWORD dwArgc,LPTSTR* lpszArgv);
    void WINAPI ControlHandler(DWORD dwCtrlCode);

    //主程序入口
    int main(int argc,char** argv)
    {
     //未带参数
     if(argc==1)
     {
      SERVICE_TABLE_ENTRY ServiceTableEntry[]={{ServiceName,ServiceMain},{NULL,NULL}};
      if(!StartServiceCtrlDispatcher(ServiceTableEntry))
      {
       printf("StartServiceCtrlDispatcher failed!\n");
       return 1;
      }
      return 0;
     }

     //参数不正确
     if(argc!=2)
     {
      ShowHelp();
      return 0;
     }
     
     //参数可识别
     
     //显示帮助
     if(!strcmp("/?",argv[1]))  
     {
      ShowHelp();  
      return 0;
     }
     //安装服务
     if(!strcmp("/i",argv[1]))
     {
      InsallService();
      return 0;
     }
     //移除服务
     if(!strcmp("/r",argv[1]))
     {
      RemoveService();
      return 0;
     }
     
     //参数不可识别
     ShowHelp();
     
     return 0;
    }

    //显示帮助
    void ShowHelp()
    {
     //显示参数提示
     printf("parameters:\n");
     printf("/?      show this help\n");
     printf("/i      install the service\n");
     printf("/r      remove the service\n");
    }

    //安装服务
    void InsallService()
    {
     SC_HANDLE schService,schSCManager;
     char FileName[256],DisplayName[]="NT Service";
     //获取文件名
     if (GetModuleFileName(0,FileName,256)==0) return;
     //打开服务管理器
     schSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
     if (schSCManager==0)
     {
      printf("Open SCManager failed!\n");
      return;
     }
     //创建服务
     schService=CreateService(schSCManager,ServiceName,DisplayName,SERVICE_ALL_ACCESS, SERVICE_WIN32_OWN_PROCESS, SERVICE_DEMAND_START,
     SERVICE_ERROR_NORMAL,FileName,NULL,NULL,NULL,NULL,NULL);
     if (schService>0)
     {
      printf("Service %s installed!\n",ServiceName);
      //关闭服务
      CloseServiceHandle(schService);
     }
     else
     {
      printf("Service %s install failed!\n",ServiceName);
     }
     //关闭服务控制器
     CloseServiceHandle(schSCManager);
    }

    //移除服务
    void RemoveService()
    {
     SC_HANDLE schService,schSCManager;
     //打开服务管理器
     schSCManager=OpenSCManager(NULL,NULL,SC_MANAGER_ALL_ACCESS);
     if (schSCManager==0)
     {
      printf("Open SCManager failed!\n");
      return;
     }
     //打开服务
     schService=OpenService(schSCManager,ServiceName, SERVICE_ALL_ACCESS);
     if (schService==0)
     {
      printf("Cann't open service!\n");
      //关闭服务
      CloseServiceHandle(schSCManager);
      return;
     }
     else
     {
      //停止服务
      if(ControlService(schService, SERVICE_CONTROL_STOP, &ssStatus))
      {
       //查询服务状态
       while(QueryServiceStatus(schService, &ssStatus))
       {
        if(ssStatus.dwCurrentState==SERVICE_STOP_PENDING) printf("%s",".");
        else break;
       }
       if(ssStatus.dwCurrentState==SERVICE_STOPPED) printf("Service Stoped Now!\n");
       else
       {
        printf("Service stop failed!\n");
        return;
       }
      }
      //删除服务
      if(DeleteService(schService))
      {
       printf("Service removed!\n");   
      }
      else
      {
       printf("Service remove failed!\n");
      }
      //关闭服务
      CloseServiceHandle(schService);
     }
     //关闭控制器
     CloseServiceHandle(schSCManager);
    }

    //服务程序入口
    void WINAPI ServiceMain(DWORD dwArgc,LPTSTR* lpszArgv)
    {
     //设置初始状态
     ssStatus.dwServiceType=SERVICE_WIN32;
     ssStatus.dwControlsAccepted=SERVICE_ACCEPT_STOP|SERVICE_ACCEPT_PAUSE_CONTINUE;
     ssStatus.dwCurrentState=SERVICE_START_PENDING;

     //注册服务
     ServiceStatusHandle=RegisterServiceCtrlHandler(ServiceName, ControlHandler);
     if(ServiceStatusHandle==0) return;
     
     //设置服务状态
     if(!SetServiceStatus(ServiceStatusHandle,&ssStatus))
     {
      //服务停止
      ssStatus.dwCurrentState=SERVICE_STOPPED;
      SetServiceStatus(ServiceStatusHandle,&ssStatus);
     }

     //服务运行
     ssStatus.dwCurrentState=SERVICE_RUNNING;
     SetServiceStatus(ServiceStatusHandle,&ssStatus);
    }

    //服务控制器
    void WINAPI ControlHandler(DWORD dwCtrlCode)
    {
     //识别控制码
     switch(dwCtrlCode)
     {
      //暂停
      case SERVICE_CONTROL_PAUSE:
       ssStatus.dwCurrentState=SERVICE_PAUSED;
       break;
      //继续
      case SERVICE_CONTROL_CONTINUE:
       ssStatus.dwCurrentState=SERVICE_RUNNING;
       break;
      //停止
       case SERVICE_CONTROL_STOP:
       ssStatus.dwCurrentState=SERVICE_STOPPED;
       SetServiceStatus(ServiceStatusHandle,&ssStatus);
       break;
     }
     
     //设置服务状态
     SetServiceStatus(ServiceStatusHandle,&ssStatus);

     return;
    }

    注:各函数的详细说明请参考MSDN。

  • 相关阅读:
    最简单跨平台的日志库
    linux文件锁
    Linux 获取屏幕分辨率与窗口行列数(c/c++)
    linux 信号机制
    记一次函数异常(getopt_long)
    程序单实例运行
    简单地 Makefile 书写
    学习go的一些笔记
    20200930 10. Netty 核心源码剖析
    20200930 9. TCP 粘包和拆包 及解决方案
  • 原文地址:https://www.cnblogs.com/MaxWoods/p/312418.html
Copyright © 2020-2023  润新知