使用Python C API时如何在Windows上中断Python子进程? [英] How to interrupt Python subprocesses on Windows when using Python C API?
问题描述
我可以通过以下方式中断Windows中的子进程
I'm able to interrupt my subprocesses in Windows with
import ctypes
ctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, _proc.pid)
但仅当我通过正常的Python进程运行它时.
but only if I run it via normal Python process.
当我使用Python C API通过单独的启动器程序运行相同的代码时(下面的代码),上面的代码没有任何作用.
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;
}
原来,pythonw.exe
也会出现相同的问题.
Turns out the same problems comes with pythonw.exe
.
推荐答案
这就是我最终在不刷新控制台窗口的情况下分配控制台的方法(感谢@eryksun提供的指针):
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.
这篇关于使用Python C API时如何在Windows上中断Python子进程?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!