【问题标题】:Terminate a child process with ctrl+c after CreateProcess in c++ (WinAPI)在 c++ 中的 CreateProcess 之后使用 ctrl+c 终止子进程(WinAPI)
【发布时间】:2020-04-03 12:22:38
【问题描述】:

我正在使用 WinAPI 的 CreateProcessA() 函数创建一个进程,并且我试图在用户按下 Ctrl+C 键时终止子进程,但我在 msdn 文档上只能找到 SetConsoleControlHandler,它在我的理解中,将控制处理程序设置为当前进程,而不是子进程。

我正在寻找一种方法来设置子进程的控制处理程序,方法是使用该进程的句柄或类似的东西:

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

SetConsoleControlHandler(hProcess, myControlhandler, TRUE);

我该怎么做?

【问题讨论】:

  • 你不能做任何事情来让子进程处理 ctrc+c 除非它已经这样做了。如果是,那么您可以使用stackoverflow.com/questions/813086/…
  • 我能想到的唯一可能是inject code 进入从子进程中调用SetConsoleControlHandler 的子进程。
  • Windows 使用 Job Objects 让您可以整体控制一组进程。
  • 按 ctrl-c 时是否默认终止任何控制台应用程序?
  • @ssbssa 子进程不是控制台应用程序,它是一个照片编辑程序(我现在用的是ms-paint,以后会是别的)。

标签: c++ winapi process


【解决方案1】:

如果你想在父进程(控制台)中使用“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;
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-05-11
    • 1970-01-01
    • 2013-05-12
    • 1970-01-01
    • 1970-01-01
    • 2011-04-14
    • 1970-01-01
    相关资源
    最近更新 更多