Frage

Gibt es eine Möglichkeit, einen Prozess begann mit der subprocess.Popen Klasse mit dem „Shell“ Argumente auf „True“ zu beenden? In der Arbeits minimal Beispiel unten (verwendet wxPython) Sie können einen Editor-Prozess glücklich öffnen und beenden, aber wenn Sie die Popen „Shell“ Argument ändern auf „True“, dann wird der Editor-Prozess nicht beenden.

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()

Bitte für die Zwecke dieser Frage akzeptieren, dass „Shell“ muss gleich „True“.

War es hilfreich?

Lösung 3

Auf der Grundlage der in Thomas Watnedal Antwort gegeben Spitze, wo er das ist nur die Schale weist darauf hin, tatsächlich in dem Beispiel getötet zu werden, habe ich die folgende Funktion angeordnet, die das Problem für mein Szenario in Mark gegeben, basierend auf dem Beispiel löst Hammonds PyWin32 Bibliothek:

procname ist der Name des Verfahrens, wie in der Task-Manager ohne die Erweiterung gesehen, z.B. Ffmpeg.exe wäre killProcName ( "FFMPEG"). Beachten Sie, dass die Funktion ist relativ langsam, da es Aufzählung aller laufenden Prozesse durchführt, um das Ergebnis nicht sofort ist.

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)

Andere Tipps

Warum verwenden Sie shell=True?

Nur tut es nicht. Sie brauchen es nicht, es ruft die Schale und das ist nutzlos.

Ich akzeptiere nicht, es wird True hat, weil es nicht. Mit shell=True bringt Sie nur Probleme und keinen Nutzen. vermeiden Sie es einfach um jeden Preis. Es sei denn, Sie einige Shell-interne Befehl ausführen, Sie brauchen es nicht, immer .

Wenn-Shell = True und den Prozess beenden aufrufen, werden Sie die Schale tatsächlich zu töten, nicht die Notizblock-Prozess. Die Schale würde, was auch immer in dem COMSPEC-Umgebungsvariable angegeben wird.

Die einzige Art, wie ich zu töten diesen Notizblock Prozess denken kann, wäre Win32process.EnumProcesses () zu verwenden, um den Prozess zu suchen, dann töten sie win32api.TerminateProcess verwenden. Sie werden jedoch nicht in der Lage sein, den Notizblock Prozess aus anderen Prozessen mit dem gleichen Namen zu unterscheiden.

Wenn Sie wirklich das shell=True Flag benötigen, dann ist die Lösung, die den start Shell-Befehl mit der /WAIT Flagge zu verwenden. Mit diesem Flag wird der start Prozess wartet für ihr Kind zu beenden. Dann wird unter Verwendung zum Beispiel des psutil Modul können Sie erreichen, was Sie wollen mit der folgenden Sequenz:

>>> import psutil
>>> import subprocess
>>> doc = subprocess.Popen(["start", "/WAIT", "notepad"], shell=True)
>>> doc.poll()
>>> psutil.Process(doc.pid).get_children()[0].kill()
>>> doc.poll()
0
>>> 

Nach der dritten Zeile erscheint Editor. poll kehrt None solange das Fenster offen dank der /WAIT Flagge ist. Nach der Tötung verschwindet start des Kindes Editor-Fenster, und poll gibt den Exit-Code.

Python 2.6 hat eine Kill-Methode für subprocess.Popen Objekte.

http://docs.python.org/library/subprocess .html # subprocess.Popen.kill

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top