c++实现Windows后台服务,从.txt文件读取进程名和绝对路径,判断进程是否运行,同时定时监控和重启
时间: 2023-06-20 10:05:24 浏览: 151
要实现Windows后台服务,可以使用Windows API中的Service Control Manager(SCM)来创建和管理服务。以下是一个简单的实现过程:
1. 创建服务
使用CreateService函数创建服务,并指定服务名称、描述、启动类型、服务程序路径等信息。
2. 启动服务
使用StartService函数启动服务。
3. 定时监控和重启
使用定时器API(例如SetTimer)定时监控进程是否运行,如果进程未运行,则使用CreateProcess函数重启进程。
4. 读取配置文件
使用标准C++库可以读取.txt文件中的内容,并解析出进程名和绝对路径。
5. 判断进程是否运行
使用Windows API中的EnumProcesses函数获取当前正在运行的进程列表,遍历列表判断指定进程是否在运行。
下面是一个简单的示例代码:
```c++
#include <windows.h>
#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#define SERVICE_NAME "ProcessMonitor"
#define CONFIG_FILE "config.txt"
#define CHECK_INTERVAL 5000 // 5s
#define RESTART_INTERVAL 30000 // 30s
#define MAX_RESTART_COUNT 3
SERVICE_STATUS g_serviceStatus;
SERVICE_STATUS_HANDLE g_serviceStatusHandle;
HANDLE g_hStopEvent;
std::vector<std::pair<std::string, std::string>> g_processes;
void WINAPI ServiceCtrlHandler(DWORD dwCtrlCode)
{
switch (dwCtrlCode)
{
case SERVICE_CONTROL_STOP:
g_serviceStatus.dwCurrentState = SERVICE_STOP_PENDING;
SetServiceStatus(g_serviceStatusHandle, &g_serviceStatus);
SetEvent(g_hStopEvent);
break;
}
}
void WINAPI ServiceMain(DWORD dwArgc, LPTSTR* lpszArgv)
{
g_serviceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_serviceStatus.dwCurrentState = SERVICE_START_PENDING;
g_serviceStatus.dwControlsAccepted = SERVICE_ACCEPT_STOP;
g_serviceStatus.dwWin32ExitCode = NO_ERROR;
g_serviceStatus.dwServiceSpecificExitCode = 0;
g_serviceStatus.dwCheckPoint = 0;
g_serviceStatus.dwWaitHint = 0;
g_serviceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
if (g_serviceStatusHandle == NULL)
{
return;
}
g_serviceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(g_serviceStatusHandle, &g_serviceStatus);
// read config file
std::ifstream config(CONFIG_FILE);
if (!config)
{
return;
}
std::string processName, processPath;
while (config >> processName >> processPath)
{
g_processes.push_back(std::make_pair(processName, processPath));
}
// monitor processes
DWORD dwRestartCount = 0;
while (WaitForSingleObject(g_hStopEvent, CHECK_INTERVAL) != WAIT_OBJECT_0)
{
bool bAllRunning = true;
for (auto& process : g_processes)
{
bool bRunning = false;
// check if process is running
DWORD aProcesses[1024], cbNeeded, cProcesses;
if (EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
{
cProcesses = cbNeeded / sizeof(DWORD);
for (DWORD i = 0; i < cProcesses; i++)
{
DWORD processId = aProcesses[i];
TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");
HANDLE hProcess = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, FALSE, processId);
if (hProcess)
{
HMODULE hModule;
DWORD cbNeeded;
if (EnumProcessModules(hProcess, &hModule, sizeof(hModule), &cbNeeded))
{
GetModuleBaseName(hProcess, hModule, szProcessName, sizeof(szProcessName) / sizeof(TCHAR));
}
CloseHandle(hProcess);
}
if (_tcscmp(szProcessName, process.first.c_str()) == 0)
{
bRunning = true;
break;
}
}
}
if (!bRunning)
{
bAllRunning = false;
// restart process
if (dwRestartCount < MAX_RESTART_COUNT)
{
STARTUPINFO si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
if (CreateProcess(process.second.c_str(), NULL, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
dwRestartCount++;
}
}
}
}
if (bAllRunning)
{
dwRestartCount = 0;
}
}
g_serviceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(g_serviceStatusHandle, &g_serviceStatus);
}
int main()
{
SERVICE_TABLE_ENTRY serviceTable[] =
{
{SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain},
{NULL, NULL}
};
if (!StartServiceCtrlDispatcher(serviceTable))
{
return GetLastError();
}
return 0;
}
```
需要注意的是,创建服务时需要管理员权限,可以在命令行中使用sc命令创建,例如:
```
sc create ProcessMonitor binPath= "C:\Path\To\ProcessMonitor.exe"
```
阅读全文