您的位置:首页 > 编程语言 > C语言/C++

C语言Windows服务程序编写-ServiceMain

2015-04-16 11:59 267 查看
      C语言编写的Windows服务程序,可以类比Linux/Unix环境下的daemon进程。

      一下是VS2010环境下的demo:

// windows_service.cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <Windows.h>
#include <stdio.h>

#define SLEEP_TIME 5000                          /*间隔时间*/
#define LOGFILE "D:\\log.txt"              /*信息输出文件*/

SERVICE_STATUS ServiceStatus;  /*服务状态*/
SERVICE_STATUS_HANDLE hStatus; /*服务状态句柄*/

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

int _tmain(int argc, _TCHAR* argv[])
{
SERVICE_TABLE_ENTRY ServiceTable[2];
ServiceTable[0].lpServiceName="Monitor";
ServiceTable[0].lpServiceProc=(LPSERVICE_MAIN_FUNCTION)ServiceMain;
ServiceTable[1].lpServiceName=NULL;
ServiceTable[1].lpServiceProc=NULL;
StartServiceCtrlDispatcher(ServiceTable);

return 0;
}

int WriteToLog(char* str)
{
FILE* pfile;
fopen_s(&pfile,LOGFILE,"a+");
if (pfile==NULL)
{
return -1;
}
fprintf_s(pfile,"%s\n",str);
fclose(pfile);

return 0;
}

/*Service initialization*/
int InitService()
{
OutputDebugString("Monitoring started.");
int result;
result = WriteToLog("Monitoring started.");

return(result);
}

/*Control Handler*/
void CtrlHandler(DWORD request)
{
switch (request)
{
case SERVICE_CONTROL_STOP:
OutputDebugString("Monitoring stopped.");
WriteToLog("Monitoring stopped.");

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

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

void ServiceMain(int argc, char** argv)
{
int error;
ServiceStatus.dwServiceType =
SERVICE_WIN32;
ServiceStatus.dwCurrentState =
SERVICE_START_PENDING;
/*在本例中只接受系统关机和停止服务两种控制命令*/
ServiceStatus.dwControlsAccepted =
SERVICE_ACCEPT_SHUTDOWN |
SERVICE_ACCEPT_STOP;
ServiceStatus.dwWin32ExitCode = 0;
ServiceStatus.dwServiceSpecificExitCode = 0;
ServiceStatus.dwCheckPoint = 0;
ServiceStatus.dwWaitHint = 0;
hStatus = ::RegisterServiceCtrlHandler(
"Monitor",
(LPHANDLER_FUNCTION)CtrlHandler);
if (hStatus == (SERVICE_STATUS_HANDLE)0)
{
WriteToLog("RegisterServiceCtrlHandler failed");
return;
}
WriteToLog("RegisterServiceCtrlHandler success");
/* Initialize Service   */
error = InitService();
if (error)
{
/* Initialization failed  */
ServiceStatus.dwCurrentState =
SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus, &ServiceStatus);
return;
}
/*向SCM 报告运行状态*/
ServiceStatus.dwCurrentState =
SERVICE_RUNNING;
SetServiceStatus (hStatus, &ServiceStatus);

/*do something you want to do in this while loop*/
MEMORYSTATUS memstatus;
while (ServiceStatus.dwCurrentState ==
SERVICE_RUNNING)
{
char buffer[16];
GlobalMemoryStatus(&memstatus);
int availmb = memstatus.dwAvailPhys/1024/1024;
sprintf_s(buffer,100,"available memory is %dMB",availmb);
OutputDebugString(buffer);
int result = WriteToLog(buffer);
if (result)
{
ServiceStatus.dwCurrentState =
SERVICE_STOPPED;
ServiceStatus.dwWin32ExitCode = -1;
SetServiceStatus(hStatus,
&ServiceStatus);
return;
}
Sleep(SLEEP_TIME);
}
WriteToLog("service stopped");

return;
}
注册&启动服务的bat脚本:

sc create Monitor binpath= D:\test\windows_service.exe
sc start Monitor
请注意binpath= 后面的空格符,空格符缺失则无法创建服务。

停止和删除服务的命令如下:

sc stop Monitor
sc delete Monitor


如有转载,请注明出处:http://blog.csdn.net/embedded_sky/article/details/45073193

作者:super_bert@csdn
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  Service windows服务