c++代码实现Windows后台服务,定时监控多个进程,重启并且能打开界面
时间: 2023-06-27 16:04:59 浏览: 170
用C++程序写的进程管理程序
4星 · 用户满意度95%
以下是一个简单的 Windows 后台服务,它会定时监控指定进程,并在进程关闭时重新启动它们。同时,该服务可以打开指定进程的界面。
```c++
#include <Windows.h>
#include <tchar.h>
#define SERVICE_NAME _T("MyService")
SERVICE_STATUS g_ServiceStatus = { 0 };
SERVICE_STATUS_HANDLE g_ServiceStatusHandle = NULL;
HANDLE g_ServiceStopEvent = INVALID_HANDLE_VALUE;
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv);
VOID WINAPI ServiceCtrlHandler(DWORD);
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam);
int _tmain(int argc, TCHAR* argv[])
{
SERVICE_TABLE_ENTRY ServiceTable[] =
{
{ SERVICE_NAME, (LPSERVICE_MAIN_FUNCTION)ServiceMain },
{ NULL, NULL }
};
if (StartServiceCtrlDispatcher(ServiceTable) == FALSE)
{
return GetLastError();
}
return 0;
}
VOID WINAPI ServiceMain(DWORD argc, LPTSTR* argv)
{
DWORD Status = E_FAIL;
g_ServiceStatusHandle = RegisterServiceCtrlHandler(SERVICE_NAME, ServiceCtrlHandler);
if (g_ServiceStatusHandle == NULL)
{
return;
}
ZeroMemory(&g_ServiceStatus, sizeof(g_ServiceStatus));
g_ServiceStatus.dwServiceType = SERVICE_WIN32_OWN_PROCESS;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_START_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwServiceSpecificExitCode = 0;
g_ServiceStatus.dwCheckPoint = 0;
if (SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus) == FALSE)
{
return;
}
g_ServiceStopEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
if (g_ServiceStopEvent == NULL)
{
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
g_ServiceStatus.dwWin32ExitCode = GetLastError();
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
return;
}
g_ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_STOP;
g_ServiceStatus.dwControlsAccepted |= SERVICE_ACCEPT_SHUTDOWN;
g_ServiceStatus.dwCurrentState = SERVICE_RUNNING;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
HANDLE hThread = CreateThread(NULL, 0, ServiceWorkerThread, NULL, 0, NULL);
WaitForSingleObject(hThread, INFINITE);
CloseHandle(g_ServiceStopEvent);
g_ServiceStatus.dwCurrentState = SERVICE_STOPPED;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
}
VOID WINAPI ServiceCtrlHandler(DWORD CtrlCode)
{
switch (CtrlCode)
{
case SERVICE_CONTROL_STOP:
if (g_ServiceStatus.dwCurrentState != SERVICE_RUNNING)
break;
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 4;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
SetEvent(g_ServiceStopEvent);
break;
case SERVICE_CONTROL_SHUTDOWN:
g_ServiceStatus.dwControlsAccepted = 0;
g_ServiceStatus.dwCurrentState = SERVICE_STOP_PENDING;
g_ServiceStatus.dwWin32ExitCode = 0;
g_ServiceStatus.dwCheckPoint = 3;
SetServiceStatus(g_ServiceStatusHandle, &g_ServiceStatus);
SetEvent(g_ServiceStopEvent);
break;
default:
break;
}
}
DWORD WINAPI ServiceWorkerThread(LPVOID lpParam)
{
while (WaitForSingleObject(g_ServiceStopEvent, 0) != WAIT_OBJECT_0)
{
// 监控进程并重启
STARTUPINFO si = { sizeof(si) };
PROCESS_INFORMATION pi;
// 进程路径和名称
TCHAR szProcessPath[] = _T("C:\\Windows\\notepad.exe");
if (!CreateProcess(szProcessPath, NULL, NULL, NULL, FALSE, NORMAL_PRIORITY_CLASS, NULL, NULL, &si, &pi))
{
// 进程启动失败,可以在这里记录日志
}
else
{
// 进程启动成功,可以在这里记录日志
// 等待进程结束
WaitForSingleObject(pi.hProcess, INFINITE);
// 关闭句柄
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
// 等待一段时间后重启
Sleep(5000);
}
return ERROR_SUCCESS;
}
```
上述代码会定时监控 C:\Windows\notepad.exe 进程,并在进程关闭时重新启动它。你可以将 szProcessPath 改为你所需的进程路径和名称。如果你需要打开进程的界面,可以在 CreateProcess 函数的第一个参数中指定要启动的应用程序路径和名称。
要安装该服务,你需要使用管理员权限打开命令提示符,然后运行以下命令:
```
sc create MyService binPath= "C:\path\to\MyService.exe"
```
其中,MyService 是服务名称,C:\path\to\MyService.exe 是服务可执行文件的路径。你需要将该路径改为你自己的可执行文件路径。
要启动该服务,你可以使用以下命令:
```
net start MyService
```
要停止该服务,你可以使用以下命令:
```
net stop MyService
```
注意:在 Windows 系统中,服务运行时没有桌面交互权限,因此无法直接打开界面。如果你需要打开界面,你可以使用 CreateProcess 函数的第一个参数指定要启动的应用程序路径和名称,该应用程序应具有桌面交互权限。
阅读全文