Завершить дочерний процесс с помощью Ctrl + c после CreateProcess в C ++ (WinAPI) - PullRequest
0 голосов
/ 03 апреля 2020

Я создаю процесс с помощью функции CreateProcessA() WinAPI и пытаюсь завершить дочерний процесс, когда пользователь нажимает клавиши Ctrl + C, но все, что я могу найти в документации MSDN, это SetConsoleControlHandler, который, в моем понимании, устанавливает обработчик элемента управления для текущего процесса, а не дочернего процесса.

Я ищу способ установить обработчик элемента управления для дочернего процесса, используя дескриптор этого процесса или что-то еще как это:

HANDLE hProcess;    // A handle to the child process after the CreateProcess function.

SetConsoleControlHandler(hProcess, myControlhandler, TRUE);

Как я могу сделать что-то подобное?

1 Ответ

1 голос
/ 06 апреля 2020

Если вы хотите использовать «Ctrl + C» в родительском процессе (консоли) для завершения дочернего процесса, вы можете вызвать TerminateProcess в функции обратного вызова процедуры обработчика:

#include <Windows.h>
#include <iostream>
PROCESS_INFORMATION pi = { 0 };

BOOL WINAPI CtrlHandler(DWORD fdwCtrlType)
{
    switch (fdwCtrlType)
    {
        // Handle the CTRL-C signal. 
    case CTRL_C_EVENT:
        printf("Ctrl-C event\n\n");
        TerminateProcess(pi.hProcess, 0);
        return TRUE;
    default:
        return FALSE;
    }
}
int main()
{
    STARTUPINFO si = { 0 };
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = true;

    BOOL ret = CreateProcess("C:\\Windows\\System32\\mspaint.exe", NULL, NULL, NULL, false, 0, NULL, NULL, &si, &pi);

    SetConsoleCtrlHandler(CtrlHandler, true);
    WaitForSingleObject(pi.hProcess, -1);
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return 0;
}

Если вы хотите использовать «Ctrl + C» в дочернем процессе, вы можете отслеживать низкоуровневые события ввода с клавиатуры:

#include <Windows.h>
#include <iostream>
PROCESS_INFORMATION pi = { 0 };
HHOOK hook;
LRESULT CALLBACK LowLevelKeyboardProc(int code, WPARAM wParam, LPARAM lParam)
{
    if (code == HC_ACTION)
    {
        PKBDLLHOOKSTRUCT pkb = (PKBDLLHOOKSTRUCT)lParam;
        if (wParam == WM_KEYDOWN && pkb->vkCode == 'C')
        {
            if (GetAsyncKeyState(VK_CONTROL) < 0)
            {
                DWORD pid = 0;
                HWND hwnd = GetForegroundWindow();
                GetWindowThreadProcessId(hwnd, &pid);
                if (pid == pi.dwProcessId)
                {
                    TerminateProcess(pi.hProcess, 0);
                    PostQuitMessage(0);
                }
            }
        }
    }
    return CallNextHookEx(hook, code, wParam, lParam);
}
int main()
{
    STARTUPINFO si = { 0 };
    si.cb = sizeof(STARTUPINFO);
    si.dwFlags = STARTF_USESHOWWINDOW;
    si.wShowWindow = true;

    BOOL ret = CreateProcess("C:\\Windows\\System32\\mspaint.exe", NULL, NULL, NULL, false, 0, NULL, NULL, &si, &pi);

    hook = SetWindowsHookEx(WH_KEYBOARD_LL, LowLevelKeyboardProc, GetModuleHandle(NULL), 0);

    MSG msg;
    while (GetMessage(&msg, NULL, 0, 0))
    {
        TranslateMessage(&msg);
        DispatchMessage(&msg);
    }
    WaitForSingleObject(pi.hProcess,-1);
    UnhookWindowsHookEx(hook);
    printf("unhook\n");
    CloseHandle(pi.hThread);
    CloseHandle(pi.hProcess);
    return 0;
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...