有没有办法终止使用subprocess.Popen类启动的进程,并将"shell"参数设置为"True"?在下面的工作最小示例(使用wxPython)中,您可以愉快地打开和终止记事本进程,但是如果将Popen"shell"参数更改为"True",则记事本进程不会终止.
import wx import threading import subprocess class MainWindow(wx.Frame): def __init__(self, parent, id, title): wx.Frame.__init__(self, parent, id, title) self.main_panel = wx.Panel(self, -1) self.border_sizer = wx.BoxSizer() self.process_button = wx.Button(self.main_panel, -1, "Start process", (50, 50)) self.process_button.Bind(wx.EVT_BUTTON, self.processButtonClick) self.border_sizer.Add(self.process_button) self.main_panel.SetSizerAndFit(self.border_sizer) self.Fit() self.Centre() self.Show(True) def processButtonClick(self, event): if self.process_button.GetLabel() == "Start process": self.process_button.SetLabel("End process") self.notepad = threading.Thread(target = self.runProcess) self.notepad.start() else: self.cancel = 1 self.process_button.SetLabel("Start process") def runProcess(self): self.cancel = 0 notepad_process = subprocess.Popen("notepad", shell = False) while notepad_process.poll() == None: # While process has not yet terminated. if self.cancel: notepad_process.terminate() break def main(): app = wx.PySimpleApp() mainView = MainWindow(None, wx.ID_ANY, "test") app.MainLoop() if __name__ == "__main__": main()
为了这个问题,请接受"shell"必须等于"True".
你为什么用shell=True
?
只是不要这样做.你不需要它,它会调用shell而且没用.
我不接受它True
,因为它没有.使用shell=True
只会带来问题,没有任何好处.不惜一切代价避免它.除非你运行一些shell内部命令,你不需要它,永远.
当使用shell = True并在进程上调用terminate时,实际上是在杀死shell而不是记事本进程.shell将是COMSPEC环境变量中指定的任何内容.
我能想到杀死这个记事本进程的唯一方法是使用Win32process.EnumProcesses()来搜索进程,然后使用win32api.TerminateProcess将其终止.但是,您无法将记事本进程与具有相同名称的其他进程区分开来.