Win32 Service的简单封装
前段时间学习Windows程序设计,刚好学到Win32 Service,于是写了两个简单的类:BaseService和ServiceCtrl。虽然功能比较简单,但是也能适用于大多数情况。下面介绍一下简单用法,如果你刚好需要写一些简单的服务程序,这两个类也许能派上用场:
1. BaseServiceBaseService.h
1
#ifndef BASE_SERVICE_H
2
#define BASE_SERVICE_H
3
4class
BaseService {
5public
:
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();
15private
:
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
6class BeepService : public
BaseService {
7public
:
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
}
24private
:
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
6int 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
4class
ServiceCtrl {
5public
:
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
8int 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 }