#include <windows.h>
#include <wtsapi32.h>
#pragma comment(lib,"wtsapi32.lib")
#include <iostream>
typedef struct _process_information
{
HANDLE wait_event;
HANDLE process_handle;
int process_id;
}process_information;
void __stdcall on_process_exit_event(void* parameter, unsigned char timer)
{
if (parameter)
{
process_information* info = (process_information*)parameter;
unsigned long exit_code = 0;
int ret = GetExitCodeProcess(info->process_handle, &exit_code);
printf("%d process exit code is %d \n", info->process_id, exit_code);
ret = CloseHandle(info->process_handle);
ret = UnregisterWait(info->wait_event);
delete info;
}
}
bool install_process_exit_event()
{
bool ret = false;
DWORD count = 0;
PWTS_PROCESS_INFOA pi{ 0 };
if (WTSEnumerateProcessesA(NULL, 0, 1, &pi, &count))
{
for (DWORD i = 0; i < count; i++)
{
if (GetCurrentProcessId() != pi[i].ProcessId)
{
HANDLE h = OpenProcess(THREAD_QUERY_LIMITED_INFORMATION | SYNCHRONIZE, FALSE, pi[i].ProcessId);
if (h != NULL && h != INVALID_HANDLE_VALUE)
{
process_information* info = new process_information;
info->process_handle = h;
info->process_id = pi[i].ProcessId;
if (RegisterWaitForSingleObject(&info->wait_event, h, on_process_exit_event, info, INFINITE, WT_EXECUTEONLYONCE))
{
ret = true;
}
}
}
}
WTSFreeMemory(pi);
}
return ret;
}
bool install_process_exit_event(int process_id)
{
bool ret = false;
HANDLE h = OpenProcess(THREAD_QUERY_LIMITED_INFORMATION | SYNCHRONIZE, FALSE, process_id);
if (h != NULL && h != INVALID_HANDLE_VALUE)
{
process_information* info = new process_information;
if (info)
{
info->process_handle = h;
info->process_id = process_id;
if (RegisterWaitForSingleObject(&info->wait_event, h, on_process_exit_event, info, INFINITE, WT_EXECUTEONLYONCE))
{
ret = true;
}
}
}
return ret;
}
int main(int argc, char* argv[])
{
install_process_exit_event();
printf("%c", getchar());
return 0;
}