Windows上的Python 2.6:如何使用“ shell = True”参数终止subprocess.Popen?
有没有一种方法可以终止以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”。
-
根据Thomas Watnedal的回答中的提示,他指出示例中实际上只是外壳被杀死,我根据Mark
Hammond的PyWin32库中给出的示例,安排了以下函数来解决我的方案的问题。 :procname是在任务管理器中看到的没有扩展名的进程的名称,例如FFMPEG.EXE将是killProcName(“
FFMPEG”)。请注意,该函数相当慢,因为它对所有当前正在运行的进程进行枚举,因此结果不是即时的。import win32api import win32pdhutil import win32con def killProcName(procname): """Kill a running process by name. Kills first process with the given name.""" try: win32pdhutil.GetPerformanceAttributes("Process", "ID Process", procname) except: pass pids = win32pdhutil.FindPerformanceAttributesByName(procname) # If _my_ pid in there, remove it! try: pids.remove(win32api.GetCurrentProcessId()) except ValueError: pass handle = win32api.OpenProcess(win32con.PROCESS_TERMINATE, 0, pids[0]) win32api.TerminateProcess(handle, 0) win32api.CloseHandle(handle)