文档章节

Win32 Service的简单封装

rise-worlds
 rise-worlds
发布于 2016/06/20 13:41
字数 761
阅读 13
收藏 0

前段时间学习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 \ " % - 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  }

源代码: 点击下载

本文转载自:http://www.cnblogs.com/flying_bat/archive/2007/09/25/905107.html

rise-worlds

rise-worlds

粉丝 3
博文 1755
码字总数 0
作品 0
深圳
程序员
私信 提问
Windows下MySQL zip版的简单安装

1、下载MySQL-5.5.10-win32.zip的版本。 2、解压到任意路径,比如"D:Programm Files"。 3、进入MySQL路径,复制my-small.ini为my.ini, 在[mysqld]部分添加 basedir = "D:/Program Files/My......

SANSOM
2013/10/17
90
0
Nebula3的Input系统

相对于其他的子系统来说, 输入系统是比较简单的. 很多游戏根本就没有对这一块进行封装, 而直接采用了Win32的消息机制. 不过经过封装的输入系统使用起来很方便, 呵呵. N3中有三种输入设备, 键...

长平狐
2012/11/12
56
0
用C/C++编写window服务

Windows 服务被设计用于需要在后台运行的应用程序以及实现没有用户交互的任务。为了学习这种控制台应用程序的基础知识,C(不是C++)是最佳选择。本文将建立并 实现一个简单的服务程序,其功...

geek_loser
2016/03/04
349
0
Windows 10偷偷增加了几种Service类型,用处不明

老的sc里,类型选项大概只有6个,绝对不到10个 own|share|interact|kernel|filesys|rec https://technet.microsoft.com/en-us/library/cc990289.aspx 现在Windows 10里有 own|share|interact......

Q_J
2015/12/19
90
0
MFC、SDK和API有什么区别

MFC、SDK和API有什么区别 MFC Microsoft Foundation Class 微软函数类库 SDK (Software Development Kit,软件开发包) 软件开发包通常是一系列API函数,而MFC 是由微软公司提供的对API封装...

huanongkou
2013/03/20
2.3K
0

没有更多内容

加载失败,请刷新页面

加载更多

android抓取app启动类

adb shell,然后logcat | grep "ActivityManager: START"

安卓工程师王恒
26分钟前
13
0
并发编程之Java锁

一、重入锁 锁作为并发共享数据,保证一致性的工具,在JAVA平台有多种实现(如 synchronized(重量级) 和 ReentrantLock(轻量级)等等 ) 。这些已经写好提供的锁为我们开发提供了便利。 重入锁...

codeobj
30分钟前
11
0
云栖深度干货 | 打造“云边一体化”,时序时空数据库TSDB技术原理深度解密

本文选自云栖大会下一代云数据库分析专场讲师自修的演讲——《TSDB云边一体化时序时空数据库技术揭秘》 自修 —— 阿里云智能数据库产品事业部高级专家 认识TSDB 第一代时序时空数据处理工具...

开源中国小二
30分钟前
9
0
mobile-nfv运行步骤

1. 编译过程 在 [workspaces] 的 <workdir> 目录运行以下命令: $ nfv-build make clean all... $ nfv-build make mobile-package...*** PACKAGE BUILT AT: /vob/BUG_117504/casa/nfv/b......

Robotcl_Blog
40分钟前
12
0
如何对邮箱做域名验证

做客户开发的时候,邮件群发仍然是个有效的手段。如果发海外邮件的话,选个服务器在国外的邮箱比较好,因为邮件抵达率会比较高一些。比如gmail, zoho mail等等,都可以。本文以zoho mail为例...

Zoho云服务
40分钟前
15
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部