I tried to write a small POC (Win32 application) that will invoke "calc.exe" using CreateProcess() and periodically obtain the status (is it still running or was it closed) using GetExitCodeProcess().
My code is "quick and dirty" only for the purpose of finding out how to use GetExitCodeProcess(), or whether I should use another method, or maybe calc.exe isn't the ideal process for such POC. That being said, I need to use CMD and am looking for a solution that will allow me to monitor a process that encapsulates CMD in it, as in my
article about that[
^] which I am hoping to improve.
I was expecting to receive a different status when I shut down calc.exe but I always receive status 0.
What I have tried:
#include "stdafx.h"
#include "MonitorProcess.h"
#define MAX_LOADSTRING 100
#define BUFSIZE MAX_PATH
#define IDT_TIMER1 1000
PROCESS_INFORMATION pi;
BOOL DoRun(WCHAR *command)
{
BOOL Result = FALSE;
DWORD retSize;
LPTSTR pTemp = NULL;
TCHAR Command[BUFSIZE] = L"";
_tcscpy_s(Command, L"C:\\Windows\\system32\\cmd.exe /C ");
_tcscat_s(Command, command);
STARTUPINFO si;
SecureZeroMemory(&si, sizeof(STARTUPINFO));
si.cb = sizeof(STARTUPINFO);
Result = CreateProcess(
NULL,
Command,
NULL,
NULL,
FALSE,
CREATE_NO_WINDOW,
NULL,
NULL,
&si,
&pi);
if (Result == FALSE)
{
retSize = FormatMessage(FORMAT_MESSAGE_ALLOCATE_BUFFER |
FORMAT_MESSAGE_FROM_SYSTEM |
FORMAT_MESSAGE_ARGUMENT_ARRAY,
NULL,
GetLastError(),
LANG_NEUTRAL,
(LPTSTR)&pTemp,
0,
NULL);
MessageBox(NULL, pTemp, L"Error", MB_OK);
if (retSize)
{
LocalFree(pTemp);
}
}
return Result;
}
HINSTANCE hInst; WCHAR szTitle[MAX_LOADSTRING]; WCHAR szWindowClass[MAX_LOADSTRING];
ATOM MyRegisterClass(HINSTANCE hInstance);
LRESULT CALLBACK WndProc(HWND, UINT, WPARAM, LPARAM);
int APIENTRY wWinMain(_In_ HINSTANCE hInstance,
_In_opt_ HINSTANCE hPrevInstance,
_In_ LPWSTR lpCmdLine,
_In_ int nCmdShow)
{
UNREFERENCED_PARAMETER(hPrevInstance);
UNREFERENCED_PARAMETER(lpCmdLine);
LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING);
LoadStringW(hInstance, IDC_MONITORPROCESS, szWindowClass, MAX_LOADSTRING);
MyRegisterClass(hInstance);
hInst = hInstance;
HWND hWnd = CreateWindowW(szWindowClass, szTitle, WS_OVERLAPPEDWINDOW,
CW_USEDEFAULT, 0, CW_USEDEFAULT, 0, nullptr, nullptr, hInstance, nullptr);
if (!hWnd)
{
return FALSE;
}
ShowWindow(hWnd, nCmdShow);
UpdateWindow(hWnd);
DoRun((WCHAR *)L"calc.exe");
SetTimer(hWnd, IDT_TIMER1, 10000, (TIMERPROC)NULL); HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MONITORPROCESS));
MSG msg;
DWORD state;
while (GetMessage(&msg, nullptr, 0, 0))
{
if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
return (int) msg.wParam;
}
ATOM MyRegisterClass(HINSTANCE hInstance)
{
WNDCLASSEXW wcex;
wcex.cbSize = sizeof(WNDCLASSEX);
wcex.style = CS_HREDRAW | CS_VREDRAW;
wcex.lpfnWndProc = WndProc;
wcex.cbClsExtra = 0;
wcex.cbWndExtra = 0;
wcex.hInstance = hInstance;
wcex.hIcon = LoadIcon(hInstance, MAKEINTRESOURCE(IDI_MONITORPROCESS));
wcex.hCursor = LoadCursor(nullptr, IDC_ARROW);
wcex.hbrBackground = (HBRUSH)(COLOR_WINDOW+1);
wcex.lpszMenuName = MAKEINTRESOURCEW(IDC_MONITORPROCESS);
wcex.lpszClassName = szWindowClass;
wcex.hIconSm = LoadIcon(wcex.hInstance, MAKEINTRESOURCE(IDI_SMALL));
return RegisterClassExW(&wcex);
}
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
DWORD exitCode = 0;
BOOL success = FALSE;
switch (message)
{
case WM_TIMER:
{
switch (wParam)
{
case IDT_TIMER1:
success = GetExitCodeProcess(pi.hProcess, &exitCode);
break;
default:
break;
}
}
wchar_t Message[80];
swprintf(Message,80,L"Exit code = %d success = %d", exitCode, success);
MessageBox(NULL, Message, L"", MB_OK);
break;
case WM_COMMAND:
{
int wmId = LOWORD(wParam);
switch (wmId)
{
case IDM_EXIT:
DestroyWindow(hWnd);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
}
break;
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
EndPaint(hWnd, &ps);
}
break;
case WM_DESTROY:
PostQuitMessage(0);
break;
default:
return DefWindowProc(hWnd, message, wParam, lParam);
}
return 0;
}