我可以使用
中断Windows中的子进程import ctypes
ctypes.windll.kernel32.GenerateConsoleCtrlEvent(1, _proc.pid)
但仅当我通过普通的Python进程运行它时。
当我使用Python C API(代码如下)通过单独的启动程序运行相同的代码时,上面的代码没有任何效果。
我是否应该以某种方式更改我的启动器以便能够中断子进程?
#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
带来了同样的问题。
答案 0 :(得分:1)
这就是我如何在没有闪烁控制台窗口的情况下分配控制台的方式(感谢@eryksun的指针):
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()
基本上我从虚拟子进程中偷走了控制台。
答案 1 :(得分:0)
我会根据@ eryksun的评论提出一个可能的解决方案。
只做
import ctypes
ctypes.windll.kernel32.AllocConsole()
在父进程中。
不幸的是(正如eryksun所指出的那样),这也会造成不必要且令人困惑的控制台窗口。