对于后台运行的程序,比如基于C/S架构的服务器、各种监控系统的程序、或者是程序额外的功能需要后台运行来实现,在Windows平台中,服务经常会用到,这种对于需要24×7运行的程序是必备的,至少本人经常需要运用windows服务来搭建后台程序。于是查阅网上的各种资料,发现有不少的参考实例,但是使用起来有各种问题,不少是这些作者或者使用者对Windows NT Service API接口运用的不熟练或者不清楚,导致自己花费很多时间在理解这些错误的实例当中,不过折腾到最后,还是从错误中得到不少教训的。所以为了方便以后能够直接使用,不再做重复的工作,便在工作之余将Windows NT Service API接口进行了二次封装并简单的测试通过,发上来也让大家使用并指正其中的错误。

  当然,有更权威的参考实例。http://msdn.microsoft.com/en-us/library/windows/desktop/bb540476(v=vs.85).aspx

  废话不多说, 先直接贴上代码,希望不要被贱笑了...

 

  NTService.h

#ifndef _NTSERVICE_H_
#define _NTSERVICE_H_

///服务启动类型定义
enum SERVICE_STARTUP_TYPE
{
    //禁用不可启动
    SST_DISABLED=0,

    //随系统启动自动启动
    SST_AUTO_START=1,

    //命令/手动启动
    SST_DEMAND_START=2
};

///服务执行的任务对象
class ServiceTask
{
public:
    ServiceTask(){}
    virtual ~ServiceTask(){}

public:
    ///服务初始化通知
    ///@return 成功返回0, 否则-1
    ///@remark 完成后需及时返回, 不能长时间阻塞
    virtual int OnInit(int argc, char **argv){return 0;}

    ///服务启动通知
    ///@remark 服务启动阻塞执行此过程, 直至服务停止/关闭
    virtual void OnStart(){}

    ///服务停止通知
    ///@remark OnStart结束返回, 服务变为停止状态
    virtual void OnStop(){}

    ///服务暂停通知
    ///@remark OnStart暂停执行, 服务变为暂停状态
    virtual void OnPause(){}

    ///被暂停的服务恢复通知
    ///@remark OnStart恢复执行, 服务变为恢复状态
    virtual void OnContinue(){}

    ///服务被强制关闭通知
    ///@remark 通常是OS关闭时发生
    virtual void OnShutdown(){}
};

class NTServiceImpl;

///服务接口控制对象
class NTService
{
public:
    ///@param name服务名称
    ///@param canstop是否可停止
    ///@param canshutdown是否可关闭
    ///@param canpausecontinue是否可暂停继续
    NTService(const char *name,
        bool canstop=true,
        bool canshutdown=true,
        bool canpausecontinue=false);

    ~NTService();

public:
    ///检查服务是否安装
    bool IsInstalled();

    ///安装服务
    ///@param display_name服务显示的名称
    ///@param type服务启动类型
    ///@return 成功返回0, 否则-1
    int Install(const char *display_name, SERVICE_STARTUP_TYPE type);

    ///卸载服务
    ///@return 成功返回0, 否则-1
    int UnInstall();

    ///设置服务启动类型
    ///@return 成功返回0, 否则-1
    int SetStartupType(SERVICE_STARTUP_TYPE type);

    ///更新服务描述信息
    ///@return 成功返回0, 否则-1
    int UpdateDesc(const char *desc);

    ///启动服务
    ///@return 成功返回0, 否则-1
    ///@param argc启动参数个数
    ///@param argv启动参数列表
    int Start(int argc=0, const char **argv=0);

    ///停止服务
    ///@return 成功返回0, 否则-1
    int Stop();

    ///获取服务当前状态
    ///@return 成功返回状态值, 否则-1
    int GetCurrentStatus();

public:
    ///系统启动服务调用
    ///@remark 不可主动调用
    int Run(ServiceTask &service);

private:
    NTServiceImpl *m_impl;
};

#endif//_NTSERVICE_H_

 

  NTServiceImpl.h

  

#ifndef _NTSERVICE_IMPL_H_
#define _NTSERVICE_IMPL_H_
#include "NTService.h"
#include <Windows.h>
#include <string>

class NTServiceImpl
{
public:
    NTServiceImpl(const char *name,
        bool canstop, 
        bool canshutdown, 
        bool canpausecontinue);

    ~NTServiceImpl();

public:
    bool IsInstalled();
    int Install(const char *display_name, SERVICE_STARTUP_TYPE type);
    int UnInstall();
    int SetStartupType(SERVICE_STARTUP_TYPE type);
    int UpdateDesc(const char *desc);
    int Start(int argc, const char **argv);
    int Stop();
    int GetCurrentStatus();

    int Run(ServiceTask &service);

private:
    std::string m_name;
    bool m_canstop;
    bool m_canshutdown;
    bool m_canpausecontinue;
};

class NTServiceManager
{
private:
    NTServiceManager();
    ~NTServiceManager();

public:
    static bool IsInstalled(const char *name);
    static int Install(const char *name, const char *display_name, SERVICE_STARTUP_TYPE type);
    static int UnInstall(const char *name);
    static int SetStartupType(const char *name, SERVICE_STARTUP_TYPE type);
    static int UpdateDesc(const char *name, const char *desc);
    static int Start(const char *name, int argc, const char **argv);
    static int Stop(const char *name);
    static int GetCurrentStatus(const char *name);

private:
    static int GetRealStartupType(SERVICE_STARTUP_TYPE type);
};

class NTServiceHandler
{
private:
    NTServiceHandler(const std::string &name,
        bool canstop,
        bool canshutdown,
        bool canpausecontinue,
        ServiceTask &service);

    ~NTServiceHandler();

public:
    static void CreateInstance(const std::string &name,
        bool canstop,
        bool canshutdown,
        bool canpausecontinue,
        ServiceTask &service)
    {
        DestroyInstance();
        m_this =new NTServiceHandler(name, canstop, canshutdown, canpausecontinue, service);
    }
    static NTServiceHandler *GetInstance()
    {
        return m_this;
    }
    static void DestroyInstance()
    {
        if (m_this)
        {
            delete m_this;
            m_this = 0;
        }
    }

public:
    int Run();

private:
    static void ServiceMainHandler(DWORD argc, LPSTR *argv);
    static void ServiceCtrlHandler(DWORD ctrl);

private:
    void NTS_Start(DWORD argc, LPSTR *argv);
    void NTS_Stop();
    void NTS_Pause();
    void NTS_Continue();
    void NTS_Shutdown();

    void SetServiceStatus(DWORD dwCurrentState,
        DWORD dwWin32ExitCode=NO_ERROR,
        DWORD dwWaitHint=0);

    int OnInit(int argc, char **argv);
    void OnStart();
    void OnStop();
    void OnPause();
    void OnContinue();
    void OnShutdown();
    
private:
    std::string m_name;
    ServiceTask &m_service;

    SERVICE_STATUS m_status;
    SERVICE_STATUS_HANDLE m_status_handle;
    
    static NTServiceHandler *m_this;
};

NTServiceHandler *NTServiceHandler::m_this = 0;

#endif//_NTSERVICE_IMPL_H_
View Code

相关文章:

  • 2022-02-04
  • 2021-10-17
  • 2021-06-13
  • 2021-12-11
  • 2021-08-10
  • 2021-10-30
  • 2021-12-19
猜你喜欢
  • 2021-12-15
  • 2022-12-23
  • 2022-12-23
  • 2021-06-12
  • 2021-05-20
  • 2021-06-04
相关资源
相似解决方案