前段時間學習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 }
源代碼:
點擊下載