Windows 上的 Python 2.6:如何使用“shell=True"终止 subprocess.Popen争论? [英] Python 2.6 on Windows: how to terminate subprocess.Popen with "shell=True" argument?

查看:62
本文介绍了Windows 上的 Python 2.6:如何使用“shell=True"终止 subprocess.Popen争论?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

有没有办法终止以 subprocess.Popen 类启动且shell"参数设置为True"的进程?在下面的最小工作示例中(使用 wxPython),您可以愉快地打开和终止记事本进程,但是如果您将 Popenshell"参数更改为True",则记事本进程不会终止.

Is there a way to terminate a process started with the subprocess.Popen class with the "shell" argument set to "True"? In the working minimal example below (uses wxPython) you can open and terminate a Notepad process happily, however if you change the Popen "shell" argument to "True" then the Notepad process doesn't terminate.

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".

Please accept for the sake of this question that "shell" does have to equal "True".

推荐答案

根据 Thomas Watnedal 的回答中给出的提示,他指出在示例中实际上只是外壳被杀死,我安排了以下功能根据 Mark Hammond 的 PyWin32 库中给出的示例解决了我的场景的问题:

Based on the tip given in Thomas Watnedal's answer, where he points out that just the shell is actually being killed in the example, I have arranged the following function which solves the problem for my scenario, based on the example given in Mark Hammond's PyWin32 library:

procname 是在没有扩展名的任务管理器中看到的进程名称,例如FFMPEG.EXE 将是 killProcName("FFMPEG").请注意,该函数相当慢,因为它执行所有当前正在运行的进程的枚举,因此结果不是即时的.

procname is the name of the process as seen in Task Manager without the extension, e.g. FFMPEG.EXE would be killProcName("FFMPEG"). Note that the function is reasonably slow as it performs enumeration of all current running processes so the result is not instant.

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)

这篇关于Windows 上的 Python 2.6:如何使用“shell=True"终止 subprocess.Popen争论?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆