蟒蛇2.6在窗口:如何终止子流程.Popen与"空壳=True"的说法?
-
22-08-2019 - |
题
有没有一种方法,终止一个过程的开始,与子流程.Popen类与"空壳"参数设定为"真正的"?在工作最少的例子如下(使用wxPython)可以开放和终止的记事本的过程愉快地,但是如果你改变Popen"壳"参数"真正的"然后记事本过程中不会终止。
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
只给你带来问题并没有任何好处。只要避免它在所有费用。除非你运行的一些外壳内部的命令,你不需要它, 曾经.
在使用shell =真,并呼吁终止的过程,实际上是杀壳,而不是记事本进程。壳将无论是在COMSPEC环境变量指定。
我能想到的杀人这个记事本程序的唯一方法是使用Win32process.EnumProcesses()来搜索的过程中,然后使用win32api.TerminateProcess杀死它。您会但是不能够使用相同的名称来区分来自其它进程的记事本过程。
如果你真的需要shell=True
标志,那么解决的办法是使用start
shell命令与/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
返回退出代码。
2.6的Python具有用于subprocess.Popen对象杀法。
http://docs.python.org/library/subprocess html的#subprocess.Popen.kill