1、在main函数中开辟一个监测线程:
HANDLE exit_thread;
exit_thread = CreateThread(NULL, 0, run, NULL, 0, NULL);
2、在线程处理函数run中进行处理,如果父进程退出,则本程序也退出:
基本步骤如下:
(1)先获取自己的进程ID,GetCurrentProcessID()
(2) 获取进程查询句柄,调用OpenProcess()带上PROCESS_QUERY_INFORMATION标志
(3)调用NtQueryInformationProcess()来查询进程信息
(4) 获取父进程句柄,还是调用OpenProcess()
(5) 启动一个线程去等待父进程退出,WaitForSingleObject(ParentHandle, INFINITE)大功告成,这样无论是父进程正常退出,还是异常终止,子进程都能被退出。
struct ProcessBasicInformation {
LONG ExitStatus;
PVOID PebBaseAddress;
ULONG_PTR AffinityMask;
LONG BasePriority;
ULONG_PTR UniqueProcessId;
ULONG_PTR InheritedFromUniqueProcessId;
};
typedef LONG(__stdcall *FPTR_NtQueryInformationProcess) (HANDLE, ULONG, PVOID, ULONG, PULONG);
unsigned long GetParentPid()
{
ULONG_PTR ppid = 0;
DWORD pid = GetCurrentProcessId();
HANDLE hcurrent = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid);
if (hcurrent)
{
FPTR_NtQueryInformationProcess NtQueryInformationProcess = (FPTR_NtQueryInformationProcess)GetProcAddress(GetModuleHandle("ntdll.dll"),
"NtQueryInformationProcess");
if (NtQueryInformationProcess != NULL)
{
ProcessBasicInformation pbi;
if (NtQueryInformationProcess(hcurrent, 0, (void*)&pbi, sizeof(pbi), NULL) == 0)
{
ppid = pbi.InheritedFromUniqueProcessId;
}
}
CloseHandle(hcurrent);
}
return ppid;
}
DWORD WINAPI run(LPVOID lpparameter)
{
ULONG_PTR pPid = GetParentPid();
HANDLE pHandle = OpenProcess(PROCESS_QUERY_INFORMATION | SYNCHRONIZE, FALSE, pPid);
if (WaitForSingleObject(pHandle, INFINITE) == WAIT_OBJECT_0)
{
exit(0);
}
return 0;
}