Windows上的Python 2.6:如何使用“ shell = True”参数终止subprocess.Popen?

发布于 2021-01-29 14:11:17

有没有一种方法可以终止以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”。

关注者
0
被浏览
156
1 个回答
  • 面试哥
    面试哥 2021-01-29
    为面试而生,有面试问题,就找面试哥。

    根据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)
    


知识点
面圈网VIP题库

面圈网VIP题库全新上线,海量真题题库资源。 90大类考试,超10万份考试真题开放下载啦

去下载看看