写一个Windows上的守护进程(1)开篇

最近由于工作需要,要写一个守护进程,主要就是要在被守护进程挂了的时候再把它启起来。说起来这个功能是比较简单的,但是我前一阵子写了好多现在回头看起来比较糟糕的代码,所以就想这次写的顺眼一点。写完后发现,诶,还可以哟。于是就总结总结。

一.大致需求

1. 功能——当被守护进程挂掉后再次启动它

2. 可配置需要守护的进程

二.通盘考虑

1. 为了避免重复造轮子,况且有的轮子可能自己也造不出来,上boost库

2. 为了能够获得较高的权限和能够开机自动启动,将其编写为一个Windows服务

3. 配置文件使用xml存储,使用rapidxml库解析

4. 为了使其更具有通用性,我又加了个功能:执行周期任务。周期任务又分了两种,一种是时间点任务,就是每到几点几分执行任务,另一种是时间间隔任务,就是每隔多少分钟执行任务

三.第一个话题:日志模块

俗话讲,粮草未动,兵马先行。窃以为日志模块就像粮草一样,所以最先开始写日志模块。

然而有人会问日志模块这种轮子多得很,不是说好不重复造轮子的吗?这当然是有原因的。

1. 我所见过的日志模块无非就提供几种字符串Log接口,实践而知,在Windows上,我们经常会用到GetLastError去获取错误码,以前我总是写

ErrorLog("xxx fail, error code: %lu", GetLastError());

写得多了,就觉得麻烦了,能不能简化一下?

2. 有的时候我就想往日志文件里头记一段二进制数据,不管可不可读。但是没有直接记录字节数据的日志接口

3. 熟悉Windows编程的同学都知道,API有A/W之分,那是因为字符(串)参数有宽窄之分,有一些日志库根本就没有考虑这个,只提供char版本的接口,我要是想传入wchar_t的字符串,还得自己再转一下,这写多了也麻烦啊

基于以上几点,我决定自行造轮子,要造一个舒舒服服的轮子。

以下是日志类的声明:

class CLoggerImpl : public Singleton<CLoggerImpl>
{
friend class Singleton<CLoggerImpl>; private:
CLoggerImpl(); public:
~CLoggerImpl(); public:
//if dir is empty, use exe dir
//when log file increases over max_size, we will create new log file
//if max_size is 0, use 10 * 1024 * 1024 (10MB)
bool init(const std::string& dir, const unsigned long max_size);
bool init(const std::wstring& dir, const unsigned long max_size); bool log_string(const LOG_LEVEL level, const char* file, const int line, const std::string& s);
bool log_string(const LOG_LEVEL level, const char* file, const int line, const std::wstring& ws); bool log_bytes(const LOG_LEVEL level, const char* file, const int line, const void *buf, const unsigned long len, const std::string& prefix);
bool log_bytes(const LOG_LEVEL level, const char* file, const int line, const void *buf, const unsigned long len, const std::wstring& wprefix); bool log_last_error(const LOG_LEVEL level, const char* file, const int line, CLastErrorFormat& e, const std::string& prefix);
bool log_last_error(const LOG_LEVEL level, const char* file, const int line, CLastErrorFormat& e, const std::wstring& wprefix);
};

请先关注其接口,忽略其他部分。这里用了重载的方式免去调用者对char和wchar_t的区分。

四.结束语

我决定一点一点的说,这次就这么多

源码:https://github.com/mkdym/DaemonSvc.git && https://git.oschina.net/mkdym/DaemonSvc.git

2015年10月24日星期六

写一个Windows上的守护进程(1)开篇的更多相关文章

  1. 写一个Windows上的守护进程(8)获取进程路径

    写一个Windows上的守护进程(8)获取进程路径 要想守护某个进程,就先得知道这个进程在不在.我们假设要守护的进程只会存在一个实例(这也是绝大部分情形). 我是遍历系统上的所有进程,然后判断他们的路 ...

  2. 写一个Windows上的守护进程(7)捕获异常并生成dump

    写一个Windows上的守护进程(7)捕获异常并生成dump 谁都不能保证自己的代码不出bug.一旦出了bug,最好是崩溃掉,这样很快就能被发现,若是不崩溃,只是业务处理错了,就麻烦了,可能很长时间之 ...

  3. 写一个Windows上的守护进程(6)Windows服务

    写一个Windows上的守护进程(6)Windows服务 守护进程因为要开机启动,还要高权限,所以我就把它做成Windows服务了. 关于Windows服务的官方文档,大家可以看https://msd ...

  4. 写一个Windows上的守护进程(5)文件系统重定向

    写一个Windows上的守护进程(5)文件系统重定向 在Windows上经常操作文件或注册表的同学可能知道,有"文件系统/注册表重定向"这么一回事.大致来说就是32位程序在64位的 ...

  5. 写一个Windows上的守护进程(4)日志其余

    写一个Windows上的守护进程(4)日志其余 这次把和日志相关的其他东西一并说了. 一.vaformat C++日志接口通常有两种形式:流输入形式,printf形式. 我采用printf形式,因为流 ...

  6. 写一个Windows上的守护进程(3)句柄的管理

    写一个Windows上的守护进程(3)句柄的管理 在Windows中编程,跟HANDLE打交道是家常便饭.为了防止忘记CloseHandle,我都是使用do-while-false手法: void f ...

  7. 写一个Windows上的守护进程(2)单例

    写一个Windows上的守护进程(2)单例 上一篇的日志类的实现里有个这: class Singleton<CLoggerImpl> 看名字便知其意--单例.这是一个单例模板类. 一个进程 ...

  8. 写一个Windows服务

    做了两个和Windows服务有关的项目了,最开始的时候没做过,不懂,现在明白了许多.需要注意的是,如果不想登录什么的,最后在添加安装程序的那里选择那个字长的右键属性,把启动方式改为local syst ...

  9. 写一个限制上传文件大小和格式的jQuery插件

    在客户端上传文件,通常需要限制文件的尺寸和格式,最常用的做法是使用某款插件,一些成熟的插件的确界面好看,且功能强大,但美中不足的是:有时候会碰到浏览器兼容问题.本篇就来写一个"原生态&quo ...

随机推荐

  1. 502 Proxy Error。The ISA Server denied the specified Uniform Resource Locator (URL).

    问题:部署好项目,在IE地址栏输入http://localhost/myweb/index.aspx,回车后报错:   解释: 试图访问的页面出现问题,无法显示此页面. 尝试下列: 刷新页: 单击“刷 ...

  2. WCF入门教程系列二

    一.概述 WCF能够建立一个跨平台的安全.可信赖.事务性的解决方案,是一个WebService,.Net Remoting,Enterprise Service,WSE,MSMQ的并集,有一副很经典的 ...

  3. 驱动编程思想之初体验 --------------- 嵌入式linux驱动开发之点亮LED

    这节我们就开始开始进行实战啦!这里顺便说一下啊,出来做开发的基础很重要啊,基础不好,迟早是要恶补的.个人深刻觉得像这种嵌入式的开发对C语言和微机接口与原理是非常依赖的,必须要有深厚的基础才能hold的 ...

  4. http://www.cnblogs.com/yyyyy5101/archive/2011/03/11/1981078.html

    http://www.cnblogs.com/yyyyy5101/archive/2011/03/11/1981078.html

  5. PROCEDURE_监测系统_告警信息存储过程—产生告警信息插入告警表

    create or replace procedure proc_alarmlog(in_id   in number, --采集器编码                                 ...

  6. [Head First Python]5. summary

    1- "原地"排序-转换后替换 >>> list = [2,1,3] >>> list.sort() >>> list [1, ...

  7. postgresql创建用户

    (1)内部命令create user 用户名 with superuser password '密码';              先进入数据库后用命令\h create user 查看帮助     ...

  8. 连接postgresql数据库

    初装postgresql数据库会产生默认的数据库用户postgres和同名的数据库.但是我的linux用户是jm,两者不一致,连不上数据库.于是先把linux用户切换为postgres.(数据库会为l ...

  9. information_schema.engines学习

    当前mysql实例的存储引擎信息可以从information_schema.engines 中查询到 例子: mysql> select * from information_schema.en ...

  10. Eclipse使用git最简易流程

    git有诸多好处,网上都说的很清楚了,在这里我不再赘述.对于我来说,私下里想做一些项目,而又不能很好的保存自己的代码和进行版本控制,这时候,就用到了git.下面,就以我个人为例讲讲git从0开始如何安 ...