您的位置:首页 > 其它

windows服务的简单实现(原创)

2010-10-21 13:39 483 查看
WINDOWS编程,可以使用命令行方式的,也可以使用图形界面方式的。可有一种程序它没有命令行输出,也没有图形界面。例如,实现IP功能的程序,实现DNS的程序,系统驱动,服务器程序等,他们都没有界面,也没有命令行输出。它们长期运行于内存,大部分时间处于睡眠状态,等某个操作触发了某个相关事件,它们便开始运行。要实现这样一类程序,那么必须用到WINDOWS服务了。打开控制面板-管理工具-服务,就可以看到当前系统中所有的服务。你可以停止它,可以设置开机启动等。我们不禁想问,既然有这个功能,那么怎么实现我们自己的服务呢?就我两天来查阅到的资料,我简单的讲讲WINDOWS服务的初步实现。还是那句话,如有纰漏,请务必指正。

如果直接给出代码,我想还是比较晕的。那我先来讲讲服务的运行过程。我就按照事件的发生顺序大概讲下。我先假设服务已经加载到系统中。在你开启服务的一瞬间,系统加载该服务的程序。是程序肯定要有主函数。所以服务的入口不可避免的也是int main(int argc,char **argv[]);。进入之后,先声明下服务的名称和启动句柄,说白了就是服务的入口函数,我们通常给它称作ServiceMain。然后用StartServiceCtrlDispatcher()函数,启动服务的入口函数。那么服务的入口函数中又发生了什么?首先是设置服务的启动状态,然后用RegisterServiceCtrlHandler()函数注册服务的控制函数,控制函数我们通常称作ServiceHandle。这样,服务的启动算是完成了。接下来就要设置服务的运行状态。设置完运行状态,紧接着就是这个服务的核心代码了,它到底要完成什么实际操作。大部分情况下,是设置一个循环,用来处理某事件的发生。或者设置一个调用句柄,用来设置系统发生一相关事件后的处理函数入口。到这里服务的主函数是写完了,你肯定有个疑问,怎么关闭服务呢?嗯,不要忘了我们刚刚用RegisterServiceCtrlHandler()函数注册服务的控制函数了。所以控制服务运行的内容肯定在服务的控制函数里。控制服务函数里有一个switch结构,用来判断服务要进行的操作。可以暂停,停止,重启等。

到这里一个服务就实现了。我也不多讲,我先给出网上的一个实例。很多国内的网站都有这个例子。我原以为是国内某个程序员写的。但当我到谷歌里一搜索,靠,还TM是老外写的。你说中国编程不行也就算了,连写个教程都不如人家。不过这个例子蛮经典,我就不拿自己的成果来现了。

//MemoryStatus.cpp

#include <windows.h>
#include <stdio.h>

#define SLEEP_TIME 5000
#define LOGFILE "C://MyServices//memstatus.txt"

SERVICE_STATUS ServiceStatus;
SERVICE_STATUS_HANDLE hStatus;

void ServiceMain(int argc, char** argv);
void ControlHandler(DWORD request);
int InitService();

int WriteToLog(char* str)
{
FILE* log;
log = fopen(LOGFILE, "a+");
if (log == NULL)
return -1;
fprintf(log, "%s/n", str);
fclose(log);
return 0;
}

void main()
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName = "MemoryStatus";
ServiceTable[0].lpServiceProc = (LPSERVICE_MAIN_FUNCTION)ServiceMain;

ServiceTable[1].lpServiceName = NULL;
ServiceTable[1].lpServiceProc = NULL;
// Start the control dispatcher thread for our service
StartServiceCtrlDispatcher(ServiceTable);
}

void ServiceMain(int argc, char** argv)
{
int error;
ServiceStatus.dwServiceType = SERVICE_WIN32;
ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
ServiceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP | SERVICE_ACCEPT_SHUTDOWN;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = RegisterServiceCtrlHandler(
"MemoryStatus",
(LPHANDLER_FUNCTION)ControlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
// Registering Control Handler failed
return;
}
// Initialize Service
error = InitService();
if (error)
{
// Initialization failed
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
// We report the running status to SCM.
ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);

MEMORYSTATUS memory;
// The worker loop of a service
while (ServiceStatus.dwCurrentState == SERVICE_RUNNING)
{
char buffer[16];
GlobalMemoryStatus(&memory);
sprintf(buffer, "%d", memory.dwAvailPhys);
int result = WriteToLog(buffer);
if (result)
{
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}

Sleep(SLEEP_TIME);
}
return;
}
// Service initialization
int InitService()
{
int result;
result = WriteToLog("Monitoring started.");
return(result);
}

// Control handler function
void ControlHandler(DWORD request)
{
switch(request)
{
case SERVICE_CONTROL_STOP:
WriteToLog("Monitoring stopped.");

ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
case SERVICE_CONTROL_SHUTDOWN:
WriteToLog("Monitoring stopped.");

ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus (hStatus, &ServiceStatus);
return;
default:
break;
}
// Report current status
SetServiceStatus (hStatus, &ServiceStatus);
return;
}

写着写着就忘了,回家路上突然想起来,光有这个是不能运行的。要在系统中注册写的这个服务。可以用sc.exe实现这个功能。每个系统基本都带这个工具。用sc create MemoryStatus d:/MemoryStatus.exe这个命令,来注册这个服务。用sc delete MemoryStatus来删除服务。然后打开控制面板-管理工具-服务,找到这个服务,启动。其实是可以用编程方式注册服务的。不过由于精力有限,我就不去琢磨了。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: