Let's try to implement a solution based on this answer. The current process's console is preserved in a dummy helper process. This isn't ideal.
Ideally, we'd want to follow this answer, create a helper process in its own process group, and have it launch the desired process - so that the GenerateConsoleCtrlEvent
can signal the target process directly without messing with the current console. Alas, this would require support of QProcess:: setCreateProcessArgumentsModifier
in PyQt5 - and that's not available yet :(
One option would be to generate a C++ helper process that does that.
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 is very much untested.