一个简单的服务管理程序,用于创建/修改/删除Win32服务(未涉及内核服务,如tcpip,afd等)。
除此之外可以作为服务的宿主,命令行为:
"ServiceHost.exe" service "somedll.dll" "arg1" "arg2" ......
somedll.dll需要导出Start,Stop,Continue,Pause,Shutdown(可选,用于处理系统关闭事件),RequestStop(可选,用于服务主动要求停止)
函数原型:
DWORD WINAPI Start(int argc, TCHAR * const *argv); // 参数argv[n]即为arg1,arg2,...,返回0表明成功,其它值表明失败
DWORD WINAPI Stop();
DWORD WINAPI Shutdown();
DWORD WINAPI Pause(); // 返回0表明成功,其它值表明失败
DWORD WINAPI Continue(); // 返回0表明成功,其它值表明失败
DWORD WINAPI RequestStop(DWORD (CALLBACK*)(DWORD dwErrorCode)); // 参数是一个函数指针。服务在启动时,DLL中的RequestStop(如果存在的话)将被调用,DLL可保存此函数指针。服务成功启动后,在任何需要的时候,DLL都可以通过调用此函数指针来主动要求停止服务(参数dwErrorCode为错误代码,dwErrorCode为0表明无错误)
可执行文件 源代码
摘要: 在GUI程序中使用cout/cin/printf
阅读全文
一个简单的异步日志模块,基本达到了灵活、高效、易用的目标。
此日志模块为文本日志,异步记录方式,即有单独的线程负责写日志文件。
具备以下特征:
1、可同时操作N个日志文件,N可配置;
2、可动态添加、删除和替换日志文件;
3、良好的多线程支持;
4、C++流风格的日志消息生成方式;
发布形式为ZLog.dll,使用时只需包含ZLog.h并连接ZLog.lib即可。
日志文件操作函数:
// 启动日志模块,logfile为日志文件名,level为输出到文件的最低日志等级,nQueueLength为内部缓冲队列的最大长度,一般使用默认值即可
// 日志等级由高至低分别为:LL_NONE、LL_FATAL、LL_ERROR、LL_WARNING、LL_INFO
// 例如,若level为LL_WARNING,则仅记录LL_WARNING、LL_ERROR和LL_FATAL等级的日志消息,而不记录LL_INFO等级的日志消息
// 成功启动后logfile的序号为0
// 返回0表明成功,其它值表明失败
int __cdecl startup(LPCTSTR logfile, LONG level, unsigned int nQueueLength = 256);
// 关闭日志模块
void __cdecl cleanup();
// 删除一个日志文件,fileindex指定该文件的序号(>= 0),仅有一个日志文件时,不允许删除
BOOL __cdecl removefile(unsigned int fileindex);
// 得到日志文件的大小,fileindex为该文件的序号(>= 0)
BOOL __cdecl getfilesize(unsigned int fileindex, ULARGE_INTEGER *lpuliFileSize);
// 将文件序号为fileindex的日志文件替换为newlogfile指定的文件,fileindex必需有效。
// 若当前有三个日志文件log1.txt,log2.txt和log3.txt,则序号分别为0,1,2。
// 若删除1代表的日志文件(即log2.txt),则log1.txt的序号不变,依然为0,log3.txt的序号变为1,同时序号2失效。
BOOL __cdecl replacefile(unsigned int fileindex, LPCTSTR newlogfile);
// 添加新的日志文件,newlogfile为文件名,若成功则返回新文件的序号(>= 0),若失败,返回-1。日志文件最大数量为16
int __cdecl addfile(LPCTSTR newlogfile);
以上所有函数都是线程安全的。
使用方法:
loginfo,logwarn,logerr,logfatal分别生成information,warning,error,fatal类型的日志消息;
输入参数格式与cout(ostream)基本一致,不同之处在于:
1、可接受Unicode字符串
2、第一个输入参数可为choosefile(n),其中n为目标日志文件的序号
例子:
1 #include "ZLog.h"
2
3 using namespace ZLog;
4
5 int _tmain(int argc, _TCHAR* argv[])
6 {
7 startup(TEXT("log1.txt"));
8
9 addfile(TEXT("log2.txt"));
10 addfile(TEXT("log3.txt"));
11
12 loginfo<<"log entry to log1.txt"; // log1.txt, impliedly "choosefile(0)"
13 logwarn<<choosefile(1)<<L"log entry to log2.txt"; // log2.txt
14 logerr<<choosefile(2)<<L"log entry to log3.txt"; // log3.txt
15
16 removefile(2); // remove log3.txt
17
18 logerr<<choosefile(2)<<"log entry to log3.txt"; // log3.txt has been removed, so log entry will be redirected to log1.txt
19
20 addfile(TEXT("newlog3.txt")); // add "newlog3.txt"
21 logerr<<choosefile(2)<<"log entry to newlog3.txt";
22
23 replacefile(1, TEXT("newlog2.txt")); // replace log2.txt with newlog2.txt
24
25 logfatal<<choosefile(1)<<"log entry to newlog2.txt";
26
27 replacefile(1, TEXT("newnewlog2.txt")); // replace newlog2.txt with newnewlog2.txt
28 logfatal<<choosefile(1)<<"log entry to newnewlog2.txt";
29
30 cleanup();
31 return 0;
32 }
33
上例为单线程演示,在多线程环境下同样适用。
同一个程序中,若有多个模块同时引用了ZLog.dll,只需要调用一次startup和cleanup即可,但多次调用亦无副作用。
有兴趣的朋友可以测试一下,发现任何问题请告诉我。
DLL下载 源代码下载
一个简单的服务管理程序,用于创建/修改/删除Win32服务(未涉及内核服务,如tcpip,afd等)。
除此之外可以作为服务的宿主,命令行为:
"ServiceHost.exe" service "somedll.dll" "arg1" "arg2" ......
somedll.dll需要导出Start,Stop,Continue,Pause,Shutdown(可选,用于处理系统关闭事件),RequestStop(可选,用于服务主动要求停止)
函数原型:
DWORD WINAPI Start(int argc, TCHAR * const *argv); // 参数argv[n]即为arg1,arg2,...,返回0表明成功,其它值表明失败
DWORD WINAPI Stop();
DWORD WINAPI Shutdown();
DWORD WINAPI Pause(); // 返回0表明成功,其它值表明失败
DWORD WINAPI Continue(); // 返回0表明成功,其它值表明失败
DWORD WINAPI RequestStop(DWORD (CALLBACK*)(DWORD dwErrorCode)); // 参数是一个函数指针。服务在启动时,DLL中的RequestStop(如果存在的话)将被调用,DLL可保存此函数指针。服务成功启动后,在任何需要的时候,DLL都可以通过调用此函数指针来主动要求停止服务(参数dwErrorCode为错误代码,dwErrorCode为0表明无错误)
可执行文件 源代码
模仿MSN画了一个DirectUI窗口,已经实现了静态控件,按钮,文本框,不过重绘效率还有点低,改变大小的时候响应比较慢。接下来打算把单选,复选,ComboBox等也做进去。
可执行文件下载
截图如下:
摘要: 在GUI程序中使用cout/cin/printf
阅读全文