windows服务程序亲密接触~

本文介绍了一位同学在入职考核中遇到的问题:使用C/C++编写一个Windows服务程序,该程序能定期从XML文件中读取配置并执行指定的应用程序。文章详细展示了如何构建这样一个服务程序,并附带了完整的源代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

昨天一同学入职考核,需要用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#的方法。。懒得管他了。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值