Python 2.6 auf Windows: wie beende Teilprozess.Popen mit "shell=True" argument?
Gibt es eine Möglichkeit, um einen Prozess zu beenden, begann mit dem Teilprozess.Popen Klasse mit der "shell" - argument auf "True" gesetzt? In der Arbeitsgruppe minimal-Beispiel unten (unter Verwendung von wxPython) können Sie öffnen und beenden eine Notepad-Prozesses (Editor glücklich, aber wenn Sie ändern die Popen "shell" - argument 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 übernehmen Sie für die Zwecke dieser Frage, dass "shell" nicht gleichbedeutend mit "Wahr".
- Welche version von Python?
- Verwandte: so beenden Sie ein python-subprocess gestartet mit shell=True
Du musst angemeldet sein, um einen Kommentar abzugeben.
Warum verwenden Sie
shell=True
?Tun Sie es gerade nicht. Sie brauchen es nicht, es ruft das shell-und das ist nutzlos.
Ich nicht akzeptieren, es muss
True
werden, weil es nicht. Mitshell=True
bringt dir nur Probleme und keine Vorteile. Nur vermeiden Sie es unter allen Umständen. Es sei denn, Sie mit einigen shell-interner Befehl, Sie brauchen es nicht, immer.Bei shell=True aufrufen und beenden den Prozess, Sie sind tatsächlich töten die Schale, nicht den Editor-Prozess. Die shell würde das sein, was angegeben ist in der COMSPEC-Umgebungsvariable.
Nur so kann ich mir vorstellen das töten dieser Editor-Prozess, würde die Win32process.EnumProcesses (), um die Suche für den Prozess, dann töten Sie mit win32api.TerminateProcess. Sie wird jedoch nicht in der Lage sein zu unterscheiden, wird der Editor-Prozess von den anderen Prozessen mit dem gleichen Namen.
Basierend auf den Tipp gegeben, in Thomas Watnedal Antwort, wo er weist darauf hin, dass nur die Schale ist tatsächlich getötet in dem Beispiel, habe ich angeordnet, die folgende Funktion löst das problem für mein Szenario, basierend auf dem Beispiel in Mark Hammond ' s PyWin32-Bibliothek:
procname ist der name des Prozesses, wie gesehen in den Task-Manager ohne Erweiterung, z.B. FFMPEG.EXE wäre killProcName("FFMPEG"). Beachten Sie, dass die Funktion ist relativ langsam, wie es führt eine Aufzählung aller Laufenden Prozesse, so dass das Ergebnis nicht sofort.
Wenn Sie wirklich brauchen, die
shell=True
Flagge, dann die Lösung ist die Verwendung derstart
shell-Befehl mit der/WAIT
Flagge. Mit dieser fahne, diestart
Prozess warten, für Ihr Kind zu beenden. Dann, mit zum Beispiel derpsutil
- Modul können Sie erreichen, was Sie wollen mit der folgenden Sequenz:Nach der Dritten line-Editor angezeigt.
poll
zurückNone
solange das Fenster geöffnet ist Dank der/WAIT
Flagge. Nach der Tötungstart
's child-Editor-Fenster verschwindet, undpoll
gibt den exit-code.Python 2.6 hat ein kill-Methode für den Teilprozess.Popen Objekte.
http://docs.python.org/library/subprocess.html#subprocess.Popen.kill