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

来源:互联网 发布:凯立德地图修改端口 编辑:程序博客网 时间:2024/05/27 21:07

      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.exesc start Monitor
请注意binpath= 后面的空格符,空格符缺失则无法创建服务。


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

sc stop Monitorsc delete Monitor



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

作者:super_bert@csdn

0 0
原创粉丝点击