VC编写windows服务程序

昨天一同学入职考核,需要用C/C++写一个服务程序,从XML读取配置,定期运行指定程序/脚本/命令……

同学无解。。向我求助,然后我也没写过windows服务程序,于是琢磨了一下,弄出一个很简单的DEMO。

 

先从网上掏了一个VC6的程序叫 memorystatus ,其功能主要为启动一个服务定期向文件内写入当前剩余内存。

然后看了一下windows自带一个sc.exe 用于管理服务。

再掏了个轻量级的XML解析器“Markup”,貌似是基于MFC的,没仔细看。。直接include用。

 

于是基于这三个玩意改改。。 就成这样了……

 

 

 

#include "Markup.h"
#include <stdio.h>
#include <string>

using namespace std;

#define SLEEP_TIME 5000  //间隔时间
#define LOGFILE "C:\\test\\log.txt" //日志文件路径
#define XMLFILE "C:\\test\\test.xml" //xml文件路径

SERVICE_STATUS          ServiceStatus; 
SERVICE_STATUS_HANDLE   hStatus; 

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

//读XML文件
string LoadXMLFile()
{
	//具体如果需要修改的话,到网上搜CMarkup类的用法
	string filepath;
	CMarkup xml;
	xml.Load(XMLFILE);
	if(xml.FindElem("PATH"))
	{
		filepath = xml.GetData();
	}
	WriteToLog(filepath.c_str());
	return filepath;
}


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

//执行应用程序
void Run()
{
	string filepath = LoadXMLFile();
	WinExec(filepath.c_str(),SW_HIDE);
}

int InitService() 
{ 
	int result;
	result = WriteToLog("Monitoring started.");
	return(result); 
}

// Control Handler
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; 
}

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);
 
   // The worker loop of a service
   while (ServiceStatus.dwCurrentState == 
          SERVICE_RUNNING)
   {
	  Run();//执行应用程序
      Sleep(SLEEP_TIME);
   }
   return; 
}

void main(int argc, char* argv[])
{ 
   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);
}

 

 

test.xml这么写:

 

<PATH>C:\test\test.bat</PATH>

 

 

这里都是用的绝对定位,服务程序默认工作目录 windows/system32,然后看了一下。。没找到C/C++怎么找服务程序的启动目录。。只找到C#的方法。。懒得管他了。

 

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值