Мониторинг текущего состояния процесса
Я попытался написать небольшое POC (Win32-приложение), которое будет вызывать "calc.exe" используя CreateProcess() и периодически получая статус (он все еще работает или был закрыт) с помощью GetExitCodeProcess().
Мой код "быстрый и грязный" только для того, чтобы узнать, как использовать GetExitCodeProcess (), или должен ли я использовать другой метод, или, может быть, calc.exe это не идеальный процесс для такого POC. Тем не менее, мне нужно использовать CMD, и я ищу решение, которое позволит мне контролировать процесс, который инкапсулирует CMD в нем, как в моем статья об этом[^] который я надеюсь улучшить.
Я ожидал получить другой статус, когда отключусь calc.exe но я всегда получаю статус 0.
Что я уже пробовал:
// MonitorProcess.cpp : Defines the entry point for the application. // #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; } // Global Variables: HINSTANCE hInst; // current instance WCHAR szTitle[MAX_LOADSTRING]; // The title bar text WCHAR szWindowClass[MAX_LOADSTRING]; // the main window class name // Forward declarations of functions included in this code module: 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); // TODO: Place code here. // Initialize global strings LoadStringW(hInstance, IDS_APP_TITLE, szTitle, MAX_LOADSTRING); LoadStringW(hInstance, IDC_MONITORPROCESS, szWindowClass, MAX_LOADSTRING); MyRegisterClass(hInstance); // Perform application initialization: hInst = hInstance; // Store instance handle in our global variable 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, // handle to main window IDT_TIMER1, // timer identifier 10000, // 10-second interval (TIMERPROC)NULL); // no timer callback HACCEL hAccelTable = LoadAccelerators(hInstance, MAKEINTRESOURCE(IDC_MONITORPROCESS)); MSG msg; DWORD state; // Main message loop: while (GetMessage(&msg, nullptr, 0, 0)) { if (!TranslateAccelerator(msg.hwnd, hAccelTable, &msg)) { TranslateMessage(&msg); DispatchMessage(&msg); } } return (int) msg.wParam; } // // FUNCTION: MyRegisterClass() // // PURPOSE: Registers the window class. // ATOM MyRegisterClass(HINSTANCE hInstance) { WNDCLASSEXW wcex; // note: this is the hProcess returned from OpenProcess 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); } // // FUNCTION: WndProc(HWND, UINT, WPARAM, LPARAM) // // PURPOSE: Processes messages for the main window. // // WM_COMMAND - process the application menu // WM_PAINT - Paint the main window // WM_DESTROY - post a quit message and return // // 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); // Parse the menu selections: 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); // TODO: Add any drawing code that uses hdc here... EndPaint(hWnd, &ps); } break; case WM_DESTROY: PostQuitMessage(0); break; default: return DefWindowProc(hWnd, message, wParam, lParam); } return 0; }