I'm able to interrupt my subprocesses in Windows with
import ctypes
ctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, _proc.pid)
but only if I run it via normal Python process.
When I run the same code via a separate launcher program using Python C API (code is below), the code above doesn't have any effect.
Should I change my launcher somehow in order to be able to interrupt subprocesses?
#include <Python.h>
#include <windows.h>
int WINAPI wWinMain(HINSTANCE hInstance, HINSTANCE, PWSTR pCmdLine, int nCmdShow)
{
    LPWSTR *argv;
    int argc;
    argv = CommandLineToArgvW(GetCommandLine(), &argc);
    if (argv == NULL)
    {
        MessageBox(NULL, L"Unable to parse command line", L"Error", MB_OK);
        return 10;
    }
    Py_SetProgramName(argv[0]);
    Py_Initialize();
    PySys_SetArgvEx(argc, argv, 0);
    PyObject *py_main, *py_dict;
    py_main = PyImport_AddModule("__main__");
    py_dict = PyModule_GetDict(py_main);
    PyObject* result = PyRun_String(
        "from runpy import run_module\n"
        "run_module('thonny')\n",
        Py_file_input,
        py_dict,
        py_dict
        );
    int code;
    if (!result) {
        PyObject *ptype, *pvalue, *ptraceback;
        PyErr_Fetch(&ptype, &pvalue, &ptraceback);
        PyObject* valueAsString = PyObject_Str(pvalue);
        wchar_t* error_msg = PyUnicode_AsWideCharString(valueAsString, NULL);
        MessageBox(0, error_msg, L"Thonny startup error", MB_OK | MB_ICONERROR);
        code = -1;
    }
    else {
        code = 1;
    }
    Py_Finalize();
    return code;
}
EDIT: Turns out the same problems comes with pythonw.exe.
That's how I finally got the console allocated without flashing console window (thanks to @eryksun for the pointers):
import sys
import ctypes
kernel32 = ctypes.WinDLL('kernel32', use_last_error=True)
cmd = [sys.executable, "-c", "print('Hi!'); input()"]
child = subprocess.Popen(cmd,
                         stdin=subprocess.PIPE,
                         stdout=subprocess.PIPE,
                         stderr=subprocess.PIPE,
                         shell=True)
child.stdout.readline() # now I know subprocess is ready
result = kernel32.AttachConsole(child.pid)
if not result:
    err = ctypes.get_last_error()
    print("Could not allocate console. Error code:", err, file=sys.stderr)
child.stdin.write(b"\n") # allow subprocess to complete
child.stdin.flush()
Basically I stole the console from a dummy subprocess.
I'll propose one possible solution according to @eryksun's comment.
Just do
import ctypes
ctypes.windll.kernel32.AllocConsole() 
in parent process.
Unfortunately (as eryksun also noted), this also creates unnecessary and confusing console window.
来源:https://stackoverflow.com/questions/43450861/how-to-interrupt-python-subprocesses-on-windows-when-using-python-c-api