Давайте попробуем реализовать решение на основе этого ответа .Консоль текущего процесса сохраняется в фиктивном вспомогательном процессе.Это не идеально.
В идеале мы хотели бы следовать этому ответу , создать вспомогательный процесс в своей собственной группе процессов и заставить его запустить нужный процесс - так, чтобы GenerateConsoleCtrlEvent
мог сигнализироватьцелевой процесс напрямую, не связываясь с текущей консолью.Увы, для этого потребуется поддержка QProcess:: setCreateProcessArgumentsModifier
в PyQt5 - а это пока недоступно: (
Один из вариантов - создать вспомогательный процесс C ++, который это делает.
import win32console, win32process, win32api, win32con
def signalCtrl(qProcess, ctrlEvent=None)
if ctrlEvent is None:
ctrlEvent = win32con.CTRL_C_EVENT
has_console=False
try:
win32console.AllocConsole()
except win32api.error:
has_console=True
if !has_console:
# free the dummy console
try:
win32console.FreeConsole()
except win32api.error:
return False
if has_console:
# preserve the console in a dummy process
try:
hProc, _, pid, _ = win32process.CreateProcess(
None, "cmd.exe", None, None, True, win32con.DETACHED_PROCESS,
None, 'c:\\', win32process.STARTUPINFO())
win32console.FreeConsole()
except win32api.error:
return False
try:
# attach to the process's console and generate the event
win32console.AttachConsole(qProcess.processId())
# Add a fake Ctrl-C handler for avoid instant kill is this console
win32api.SetConsoleCtrlHandler(lambda x: True, True)
win32console.GenerateConsoleCtrlEvent(ctrlEvent, 0)
win32console.FreeConsole()
except win32api.error:
return False
if !has_console:
# we have no console to restore
return True
try:
# attach to the dummy process's console and end the process
win32console.AttachConsole(pid)
win32process.TerminateProcess(hProc, 1)
except win32api.error:
return False
return True
Thisочень непроверенный.