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.
pidis actually a process group ID, as is documented, then the behavior ofGenerateConsoleCtrlEvent(CTRL_BREAK_EVENT, pid)is undefined. In practice what it does is act likepidis 0, i.e. it broadcasts the event to every process that's attached to a console. You don't want that. It could kill a parent process that's attached to the console.GenerateConsoleCtrlEventwould work.creationflags=subprocess.CREATE_NEW_PROCESS_GROUP, so it works with normal Python. Any ideas, how to attach the launcher to a console?