Python,不能在窗口中使用Ctrl-C中断子进程



我有一些Python代码可以用子进程调用外部可执行程序,并将输出实时读回GUI,我希望随时用Ctrl-C中断外部二进制文件,但它似乎不起作用。

我正在Windows上工作。我希望在按 Ctrl-C 时停止子进程。

这是我的代码:

class binary_run():
    def __init__ (self, tcl_file_name, cmd_str, output_ctrl, exe_cwd):
        self.some_exe = "E:\some.exe"
        self.cmd = cmd = self.some_exe + cmd_str
        self.output_ctrl = output_ctrl

    def PrintOutputInRealTime(self):
        #The following two lines are to make sure the console window is hidden
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        #Start the subprocess
        process = subprocess.Popen(self.cmd, startupinfo=startupinfo, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        while True:
            try:
                output = process.stdout.readline()
                if output == '' and process.poll() is not None:
                    break
                if output:
                    self.output_ctrl.write(output)
            except KeyboardInterrupt: #Never comes here
                process.terminate()
        process.terminate()
    def run_binary(self):
        worker = Thread(target=self.PrintOutputInRealTime)
        worker.start()

感谢 @J.F.Sebastian,我没有使用 KeyboardInterrupt,而是将键(Ctrl+Delete)绑定到我的 GUI,如果键关闭,子进程将终止,它的工作原理如下:

class binary_run():
    def __init__ (self, tcl_file_name, cmd_str, output_ctrl, exe_cwd):
        self.some_exe = "E:\some.exe"
        self.cmd = self.some_exe + cmd_str
        self.output_ctrl = output_ctrl
        self.output_ctrl.Bind(wx.EVT_KEY_DOWN, self.OnKeyDown)
    def PrintOutputInRealTime(self):
        #The following two lines are to make sure the console window is hidden
        startupinfo = subprocess.STARTUPINFO()
        startupinfo.dwFlags |= subprocess.STARTF_USESHOWWINDOW
        #Start the subprocess
        self.process = subprocess.Popen(self.cmd, startupinfo=startupinfo, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        while True:
            try:
                #output = process.stdout.readline()
                output = self.process.stdout.readline()
                if output == '' and self.process.poll() is not None:
                    break
                if output:
                    self.output_ctrl.write(output)
            except KeyboardInterrupt:
                self.process.terminate()
        self.process.terminate()
    def OnKeyDown(self, event):
        controlDown = event.ControlDown()
        keycode = event.GetKeyCode()
        if (controlDown and keycode == wx.WXK_DELETE):
            wx.MessageBox('Binary got interrupted!', 'INFO', wx.OK | wx.ICON_INFORMATION)
            self.process.terminate()
    def run_binary(self):
        worker = Thread(target=self.PrintOutputInRealTime)
        worker.start()

我自己在某个时候遇到了类似的情况,当时我使用线程运行可执行文件并读取其数据。我使用以下方法来解决这个问题

import threading
import subprocess
import time
class binary_run():
    def __init__ (self):
        self.some_exe = "notepad.exe"
    def PrintOutputInRealTime(self):
        self.process = subprocess.Popen(self.some_exe,stdin=subprocess.PIPE, stdout=subprocess.PIPE)
        while True:
            try:
                output = self.process.stdout.readline()
                if output == '' and self.process.poll() is not None:
                    break
                if output:
                    self.output_ctrl.write(output)
            except:
                pass
    def KillProcess(self):
        self.process.terminate()
if __name__ == "__main__":
    x = binary_run()
    worker = threading.Thread(target=x.PrintOutputInRealTime)
    worker.start()
    try:
        while worker.isAlive():
            time.sleep(0.5)
    except KeyboardInterrupt:
            print "Got Interrupt"
            x.KillProcess()

最新更新