在Windows上,许多服务或者展示类的客户端往往都会附带开机自启/程序异常退出后自启这一功能。功能很简单,实现起来也不复杂,只需要创建一个监控程序来一直检测其是否正在运行,没运行则启动它;开机自启只需将程序路径添加到注册表中即可。
#include "stdafx.h"
#include <stdio.h>
#include <tchar.h>
#include <stdlib.h>
#include <Windows.h>
#include <io.h>
#include <iostream>
#include <Tlhelp32.h>
#include <Shlwapi.h>
#include <string.h>
#pragma comment(lib,"shlwapi.lib")
using namespace std;
//隐藏DOS窗口
#pragma comment(linker,"/subsystem:\"windows\" /entry:\"mainCRTStartup\"")
//定义路径最大程度
#define MAX_PATH_NUM 4096
//定义守护进程名称
#define PROCCESS_NAME "Test.exe"
//定义写入的注册表路径
#define SELFSTART_REGEDIT_PATH "Software\\Microsoft\\Windows\\CurrentVersion\\Run\\"
BOOL SetSelfStart()
{
char pName[MAX_PATH_NUM] = { 0 };
GetModuleFileNameA(NULL, pName, MAX_PATH_NUM);
HKEY hKey = NULL;
LONG lRet = 0;
lRet = RegOpenKeyExA(HKEY_CURRENT_USER, SELFSTART_REGEDIT_PATH, 0, KEY_ALL_ACCESS, &hKey);
if (lRet != ERROR_SUCCESS)
{
return FALSE;
}
lRet = RegSetValueExA(hKey, "TestMonitor", 0, REG_SZ, (const unsigned char*)pName, strlen(pName) + sizeof(char));
if (lRet != ERROR_SUCCESS)
{
return FALSE;
}
RegCloseKey(hKey);
return TRUE;
}
int main()
{
HANDLE hMutex = CreateMutex(NULL, FALSE, L"TestMonitor");
if (GetLastError() == ERROR_ALREADY_EXISTS)
{
CloseHandle(hMutex);
hMutex = NULL;
cout << "守护进程程序已经运行....." << endl;
return true;
}
//设置程序开机自启动
if (!SetSelfStart())
{
cout << "守护进程开机自启动失败" << endl;
}
STARTUPINFOA si;
PROCESS_INFORMATION pi;
ZeroMemory(&si, sizeof(si));
si.cb = sizeof(si);
ZeroMemory(&pi, sizeof(pi));
char pPath[MAX_PATH_NUM] = { 0 };
GetModuleFileNameA(NULL, pPath, MAX_PATH);
char *pTemp = strrchr(pPath, '\\');
*pTemp = 0x00;
strcat(pPath, "\\");
strcat(pPath, PROCCESS_NAME);
char pCmd[MAX_PATH_NUM] = { 0 };
strcat(pCmd, pPath);
do {
//检查守护程序是否存在
if (-1 != _access(pPath, 0))
{
if (!CreateProcessA(NULL, pCmd, NULL, NULL, FALSE, 0, NULL, NULL, &si, &pi))
{
cout << "守护进程启动失败,程序即将退出" << endl;
return -1;
}
cout<<"守护进程成功,ID:" << pi.dwProcessId << endl;
WaitForSingleObject(pi.hProcess, INFINITE);
cout << "守护进程退出了。。。" << endl;
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
}
else
{
cout << "守护程序不存在:" << pPath << endl;
}
Sleep(1000);
}while (true);
return 0;
}