質問

プロセスを終了する方法はあり、「真」に設定された「シェル」引数でsubprocess.Popenクラスで開始?あなたが喜んでメモ帳のプロセスを開き、終了することができます(wxPythonのを使用しています)の下にワーキング最小限の例では、あなたはpopenの「殻」引数を「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()

「シェル」は「真」にする必要がないことを、この質問のために受け入れてくださいます。

役に立ちましたか?

解決 3

彼はちょうどシェルが実際の例で殺されていることを指摘トーマスWatnedalの答えで与えられたヒントに基づいて、私はマークで示された例に基づいて、私のシナリオのための問題を解決し、以下の機能が配置されていますハモンドの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)

他のヒント

なぜあなたはshell=Trueを使用していますか?

ちょうどそれをしません。あなたは、それはシェルを呼び出し、それは無用である、それを必要としない。

私はそれがないので、Trueする必要が受け付けません。 shell=Trueを使用すると、唯一のあなたに問題なし利益をもたらします。ただ、すべてのコストでそれを避けます。あなたには、いくつかのシェルの内部コマンドを実行している場合を除き、あなたは、それを必要としないのこれまでのの。

Trueのシェルを使用して=し、プロセスに終了を呼び出すときに、あなたが実際にシェルではなく、メモ帳のプロセスを殺しています。シェルはCOMSPEC環境変数で指定されているものになります。

私はこのメモ帳のプロセスを殺すと考えることができる唯一の方法は、win32api.TerminateProcessを使用してそれを殺す、プロセスを検索するには()Win32process.EnumProcessesを用いることであろう。ただし、同じ名前を持つ他のプロセスからのメモ帳のプロセスを区別することはできません。

あなたが本当にshell=Trueフラグが必要な場合は、その解決策はstartフラグで/WAITシェルコマンドを使用することです。このフラグを使用すると、startプロセスが終了するその子のために待機します。そして、例えば psutil のモジュールを使用して、あなたが望むものを達成することができます以下の配列を有するます:

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

第三行の後にメモ帳が表示されます。 poll戻っは、ウィンドウがNoneフラグに開かおかげである限り/WAIT。殺した後startの子のメモ帳ウィンドウが消え、pollは終了コードを返します。

はPython 2.6はsubprocess.PopenオブジェクトにKill方法があります。

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

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top