zoukankan      html  css  js  c++  java
  • Win32 Service的简单封装

    前段时间学习Windows程序设计,刚好学到Win32 Service,于是写了两个简单的类:BaseService和ServiceCtrl。虽然功能比较简单,但是也能适用于大多数情况。下面介绍一下简单用法,如果你刚好需要写一些简单的服务程序,这两个类也许能派上用场:

    1. BaseService
    BaseService.h

     1  #ifndef BASE_SERVICE_H
     2 
    #define BASE_SERVICE_H
     3 

     4 class  BaseService {
     5 public
    :
     6 
        explicit BaseService(LPCTSTR szServiceName,
     7                 DWORD dwServiceType =
     SERVICE_WIN32_OWN_PROCESS,
     8                 DWORD dwStartType =
     SERVICE_AUTO_START);
     9     virtual ~
    BaseService() {}
    10     bool ParseStandardArgs(int argc, char*
     argv[]);
    11 
        bool IsInstalled();
    12 
        bool Install();
    13 
        bool Uninstall();
    14 
        bool Start();
    15 private
    :
    16     virtual void Run() = 0
    ;
    17     virtual bool OnInitialize() { return true
    ; }
    18     virtual void
     OnStop() {}
    19     virtual void
     OnPause() {}
    20     virtual void
     OnContinue() {}
    21     virtual void
     OnInterrogate() {}
    22     virtual void
     OnShutdown() {}
    23     virtual void
     OnUserControl(DWORD dwControl) {}
    24 
        ...
    25 
    };
    26 

    27 #endif/*BASE_SERVICE_H*/

    要实现自己的服务类只需从BaseService继承并且Override相关的virtual函数即可,下面示范一个BeepService类,该服务只是简单地每隔2秒beep一下,为了简单所有代码均放在.h文件中:
    BeepService.h

     1  #ifndef BEEP_SERVICE_H
     2 
    #define BEEP_SERVICE_H
     3 

     4 #include "BaseService.h"
     5 
     6 class BeepService : public  BaseService {
     7 public
    :
     8 
        BeepService(LPCTSTR szServiceName)
     9 
            :BaseService(szServiceName)
    10         ,m_bPaused(false
    )
    11         ,m_bRunning(false
    ) {}
    12 

    13     virtual void OnStop() { m_bRunning = false ; }
    14     virtual void OnPause() { m_bPaused = true
    ; }
    15     virtual void OnContinue() { m_bPaused = false
    ; }
    16     virtual void
     Run() {
    17         m_bRunning = true
    ;
    18         while
     (m_bRunning) {
    19             if (!
    m_bPaused)
    20                 Beep(800800
    );
    21             Sleep(2000
    );
    22 
            }
    23 
        }
    24 private
    :
    25     volatile
     bool m_bPaused;
    26     volatile
     bool m_bRunning;
    27 
    };
    28 

    29 #endif/*BEEP_SERVICE_H*/

    通常来说只须要Override上面的4个virtual函数就OK了:
    Run()中进行实际的工作,OnStop(),OnPause(),OnContinue()则是为了响应Service Control Manager的控制。

    test.cpp

     1 #include <windows.h>
     2 #include <tchar.h>
     3 #include <stdio.h>
     4 #include "BeepService.h"
     5 
     6 int main(int argc, char * argv[]) {
     7 

     8     BeepService beepService(_T("BeepService" ));
     9     if (!
    beepService.ParseStandardArgs(argc, argv)) {
    10         if
     (beepService.IsInstalled()) {
    11             if (!
    beepService.Start())
    12                 printf("The service can not run from command line.\n"
    );
    13         } else
     {
    14             printf("The service is not installed, "

    15                 "use \"%-i\" to install.\n", argv[0 ]);
    16 
            }
    17 
        }
    18     return 0
    ;
    19 }

    假设编译后生成的exe文件为beep.exe,则在命令行中可以如下使用:
    (1). beep -i    安装service(安装以后系统运行时会自动启动)
    (2). beep -u   卸载service(如果service正在运行,则先停止service再卸载)
    BaseServiced 的ParseStandardArgs正是用来解析上述两个命令。

    2. ServiceCtrl
    虽然Windows自带的Service Control Manager可以控制服务程序,但是很多时候我们都需要用代码控制,这就用到ServiceCtrl类,该类的接口如下:
    ServiceCtrl.h

     1  #ifndef SERVICE_CTRL_H
     2 
    #define SERVICE_CTRL_H
     3 

     4 class  ServiceCtrl {
     5 public
    :
     6 
        ServiceCtrl(LPCTSTR szServiceName);
     7     ~
    ServiceCtrl();
     8 
        bool Start();
     9 
        bool Pause();
    10 
        bool Continue();
    11 
        bool Stop();
    12 
        bool Interrogate();
    13 
        bool UserControl(DWORD dwControl);
    14     DWORD State() const
    ;
    15 
        ...
    16 
    };
    17 

    18 #endif/*SERVICE_CTRL_H*/

    接口比较直观没什么好说的,看下面的示例代码:
    test.cpp

     1 #include <windows.h>
     2 #include <tchar.h>
     3 #include <stdio.h>
     4 #include <exception>
     5 #include "BeepService.h"
     6 #include "ServiceCtrl.h"
     7 
     8 int main(int argc, char * argv[]) {
     9 

    10     try  {
    11         ServiceCtrl servCtrl(_T("BeepService"
    ));
    12         if (servCtrl.State() !=
     SERVICE_STOPPED) {
    13             printf("Service already started.\n"
    );
    14         } else
     {
    15 
                servCtrl.Start();
    16             printf("Start.\n"
    );
    17             Sleep(6000
    );
    18 
                servCtrl.Pause();
    19             printf("Pause.\n"
    );
    20             Sleep(6000
    );
    21 
                servCtrl.Continue();
    22             printf("Continue.\n"
    );
    23             Sleep(6000
    );
    24 
                servCtrl.Stop();
    25             printf("Stop.\n"
    );
    26 
            }
    27     } catch (std::exception &
    e) {
    28         printf("%s\n"
    , e.what());
    29 
        }
    30     return 0
    ;
    31 }

    源代码:点击下载
  • 相关阅读:
    pip安装不成功的解决办法
    nginx常用的请求头参数和防DDOS攻击
    nginx报错:‘open too many files’解决
    nginx根据http_user_agent来拦截访问
    centos7安装logstash
    aws创建实例ec2时关联IAM
    docker清理多余的镜像和stop的容器
    理想
    +: indexed part-select
    Features Download Pricing Mind Maps Blog XMind的快捷键
  • 原文地址:https://www.cnblogs.com/flying_bat/p/905107.html
Copyright © 2011-2022 走看看