前段时间学习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(800, 800 );
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 \"%s -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 } 
源代码:
点击下载