杀死Popen儿童进程

时间:2014-02-25 17:28:16

标签: python windows popen

这是我向社区发布的第一篇文章,但我现在已经通过搜索大约两周来了解我的情况。我似乎已经走到了死胡同,似乎无法通过反复试验或通过其他帖子阅读来找到答案。

此时我想做的就是杀死Popen和shell本身创建的进程。我必须补充一点,我是编程新手,这是我第一次“真正的”世界方面的任务。

我见过的解决方案是创建一个组ID,但这是针对Unix而我是在Windows上。 Popen.kill()和Popen.terminate()不会杀死shell的子代。由此代码启动的程序不会退出,它的PID与shell的PID不同。我对这些建议持开放态度,因为我将它作为一种学习工具和一些有用的东西。其他一些解决方案并没有破坏这个过程。我可以通过DOS和Python解释器来杀死它,但是我必须从TASKLIST手动查找PID然后输入它。我需要从这个程序中删除它。

我正在构建此代码以保存MathCad模板的多个文档,这些文档读取excel文档的值,并使用新文件名吐出已保存的文档。提前致谢。请原谅你可能看到的任何新手编码的东西,因为我只是想弄湿我的脚。

尝试和更新了其他任务(2014年2月26日):

尝试使用subprocess.call('TASKKILL ...)而不是subprocess.Popen来杀死程序。它不会杀死shell创建的子进程。尝试用subprocess.call('....',shell = True)替换proc = subprocess.Popen('....'shell = True),SendKeys函数不再起作用。尝试使用kill_proc_tree函数和“EOFError:[WinError 10054]远程主机强制关闭现有连接”的psutil函数弹出窗口。儿童计划仍然没有关闭。

如果我删除kill / terminate / close命令并让程序运行,则proc.pid与os.getpid()不同。如果我使用psutil.Process(proc.pid) - 它表示当Python解释器返回其PID时该进程不存在。如果我得到MathCadPrime.exe PID =例如来自TASKLIST的1111并使用psutil.Process(1111).parent,它显示没有父母。这可能是为什么在shell上执行TASKKILL不关闭孩子的原因?我已经完全按照我的编写方式发布了我的代码,看看你是否有大师看到我不知道的东西。

#def kill_proc_tree(pid, including_parent=True):
#    parent = psutil.Process(pid)
#    for child in parent.get_children(recursive=True):
#        child.kill()
#    if including_parent:
#        parent.kill()

import subprocess
import win32api
import win32com.client
import time
import os
import signal
import psutil

# User files
file = "C:\Directory\SubDirectory\file.mcdx"


# Command line function
# /B /D - No command line window or explorer window    
proc = subprocess.Popen('start /B /D                                            \
        "C:\Program Files\PTC\Mathcad\Mathcad Prime 2.0\" "MathcadPrime.exe"    \
        "C:\Directory\SubDirectory\file.mcdx"', shell=True)

# Set and test for active window
    focus = False
    while (focus == False):
            focus = shell.AppActivate("MathCad Prime 2.0 - " + file)
            time.sleep(1)
            if (focus == True):
                break

# Send MathCad Prime commands
shell.SendKeys('%', 0)
time.sleep(0.5)
shell.SendKeys('c', 0)
time.sleep(0.1)
shell.SendKeys('c', 0)
time.sleep(2.0)
shell.SendKeys('%', 0)
time.sleep(0.5)
shell.SendKeys('f', 0)
time.sleep(0.1)
shell.SendKeys('s', 0)
time.sleep(4.0)



#Other methods to tried to kill children:

#Method 1:
#subprocess.call("TASKKILL /F /T /PID {pid}".format(pid=proc.pid))

#Method 2:
#subprocess.Popen("TASKKILL /F /T /PID {pid}".format(pid=proc.pid))

#Method 3:
#if (int(proc.pid) > 0):
#    os.kill(proc.pid, signal.SIGTERM)

#Method 4 (used with kill_proc_tree):
#proc1 = os.getpid()
#kill_proc_tree(proc1)

2 个答案:

答案 0 :(得分:3)

感谢所有帮助人员,你帮助我得出结论。与建议略有不同,但每次都完成工作。我在家,而不是在工作(所以我写的是我的头脑),但基本上我所做的只是将TASKLIST写入文本文件并过滤掉一行代码:

os.chdir('C:\Code')
subprocess.call('TASKLIST /fi "IMAGENAME eq MathcadPrime.exe" /nh /fo csv > task.txt)

然后解析PID:

doc = open('task.txt', 'rt')
parse = doc.read()
listing = parse.split(",")
PID = listing[1]
PID = int(PID.replace('"','').replace("'",""))
os.kill(PID, signal.SIGTERM)

我希望这可以帮助别人。

答案 1 :(得分:2)

我尝试了以下代码,它对我有用:

import subprocess
import os,signal
proc = subprocess.Popen('dir /S', shell=True)
if (int(proc.pid) > 0):
    print "killing ",proc.pid
    print os.kill(proc.pid, signal.SIGTERM)

我所观察到的是,如果Popen启动的程序响应“Ctrl + C”,您可以使用signal.CTRL_C_EVENT关闭程序。如果启动的程序没有响应事件,那么必须手动关闭它。我认为,我的上述代码有效,因为cmd.exe会响应该事件。