对于后台运行的程序,比如基于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_