как передать / отправить control-c в QProcess - PullRequest
0 голосов
/ 21 мая 2018

Я пытаюсь имитировать следующую командную строку в QProcess, но я не знаю, как передать / отправить control-c с помощью QProcess.Любая помощь будет принята с благодарностью:

ПРИМЕЧАНИЕ. Не удается использовать QProcess.kill (), QProcess.terminate ()

#!/usr/bin/python

import sys, time


def main(argv):
   print ('enter main')
   time.sleep(20)
   print ('exit main')

if __name__ == "__main__":
   main(sys.argv[1:]) 

Командная строка выглядит так при нажатии control-c-

C:\>python tt.py
enter main
Traceback (most recent call last):
  File "tt.py", line 12, in <module>
    main(sys.argv[1:])
  File "tt.py", line 8, in main
    time.sleep(20)
KeyboardInterrupt

C:\>

1 Ответ

0 голосов
/ 22 мая 2018

Давайте попробуем реализовать решение на основе этого ответа .Консоль текущего процесса сохраняется в фиктивном вспомогательном процессе.Это не идеально.

В идеале мы хотели бы следовать этому ответу , создать вспомогательный процесс в своей собственной группе процессов и заставить его запустить нужный процесс - так, чтобы 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очень непроверенный.

...