用C++写一个监控服务和应用程序状态的看门狗程序
由于公司业务需要,写了一个看门狗程序。
主要功能
1.隔一小段时间检测一下服务或应用程序的状态。
2.如果服务或应用程序异常停止或者关闭,将其重新启动
上代码上代码
#include<iostream>
#include<Windows.h>
#include<shlwapi.h>
#include<atltime.h>
#include <TLHELP32.H> // 声明快照函数的头文件
HWND GetWindowHandleByPID(DWORD dwProcessID)
{
HWND h = GetTopWindow(0);
while (h)
{
DWORD pid = 0;
DWORD dwTheardId = GetWindowThreadProcessId(h, &pid);
if (dwTheardId != 0)
{
if (pid == dwProcessID/*your process id*/)
{
// here h is the handle to the window
return h;
}
}
h = GetNextWindow(h, GW_HWNDNEXT);
}
return NULL;
}
void OnTimer(UINT_PTR nIDEvent)
{
while (true)
{
BOOL bFind = FALSE;
PROCESSENTRY32 pe32;
pe32.dwSize = sizeof(pe32);
// 给系统内的所有进程拍一个快照--改函数用于获取系统指定进程的快照,也可以传入不同参数获取被这些进程使用的堆、模块和线程的快照
HANDLE hProcessSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
if (hProcessSnap == INVALID_HANDLE_VALUE)
{
//printf("CreateToolhelp32Snapshot 调用失败!\n");
//logger.LogInfo("CreateToolhelp32Snapshot 调用失败!");
}
// 遍历进程快照,轮流显示每个进程的信息
BOOL bMore = ::Process32First(hProcessSnap, &pe32);
while (bMore)
{
if (!strcmp(pe32.szExeFile, "被监控的进程名"))//服务运行的时候也有一个进程名字
{
bFind = TRUE;
//logger.LogInfo("Found it");
}
bMore = ::Process32Next(hProcessSnap, &pe32);
}
// 不要忘记清除掉snapshot 对象
::CloseHandle(hProcessSnap);
if (!bFind) //如果没有VServer启动
{
//如果不需要监控服务的话,可以把下面这段代码注释掉。
DWORD err;
SC_HANDLE sc_handle = NULL;
sc_handle = OpenSCManagerA(NULL, NULL, SERVICE_START);
if (sc_handle == NULL)
{
err = GetLastError();
//logger.LogInfo("OpenSCManagerA failed,Error:%d", err);
}
sc_handle = OpenServiceA(sc_handle, "被监控的服务名", SERVICE_START);
if (sc_handle == NULL)
{
err = GetLastError();
//logger.LogInfo("Open server failed,Error:%d", err);
}
if (!StartServiceA(sc_handle, NULL, NULL))
{
err = GetLastError();
//logger.LogInfo("Start server failed,Error:%d", err);
}
else
//logger.LogInfo("Start the server success");
if (sc_handle != NULL)
{
CloseServiceHandle(sc_handle);
}
//上面的代码是监控服务用的。下面的代码是监控应用程序用的,需要就打开
//WinExec(strAppPath, SW_NORMAL);
}
else
{
FILETIME CreationTime = { 0 };
FILETIME LastAccessTime = { 0 };
FILETIME LastWriteTime = { 0 };
FILETIME LocalTime = { 0 };
SYSTEMTIME sysTime;
//被监控的程序需要开一个线程 隔几秒钟打开关闭一下check.txt文件
HANDLE hFile = CreateFile(".//check.txt", GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, NULL, NULL);
if (INVALID_HANDLE_VALUE != hFile)
{
GetFileTime(hFile, &CreationTime, &LastAccessTime, &LastWriteTime);
FileTimeToLocalFileTime(&LastWriteTime, &LocalTime);
FileTimeToSystemTime(&LocalTime, &sysTime);
CTime time1 = CTime::GetCurrentTime();
CTime time2((int)sysTime.wYear, (int)sysTime.wMonth, (int)sysTime.wDay,
(int)sysTime.wHour, (int)sysTime.wMinute, (int)sysTime.wSecond);
CTimeSpan ts = time1 - time2;
if (ts.GetTotalSeconds() >= 30) //大于90秒没响应就关闭程序
{
//logger.LogInfo("demo.exe 90s no response,let me shut it down");
HWND hWnd = GetWindowHandleByPID(pe32.th32ProcessID);
if (NULL != hWnd)
{
HANDLE hprocess = ::OpenProcess(PROCESS_ALL_ACCESS, FALSE, pe32.th32ProcessID);
TerminateProcess(hprocess, 0);
}
}
CloseHandle(hFile);
}
}
//每隔15秒检测一次
for (int i = 0; i < 15; ++i)
Sleep(1000);
}
}
int main()
{
UINT_PTR nIDEvent;
OnTimer(nIDEvent);
getchar();
return 0;
}
以上就是程序的全部代码,如果需要将其做成服务的话可以参考这篇文章:https://blog.csdn.net/weixin_44229493/article/details/109527911