杀死Popen子进程 [英] Kill the Popen child process

查看:301
本文介绍了杀死Popen子进程的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

这是我向社区发布的第一篇文章,但是我已经通过搜索大约2周来学习到了什么.我似乎已死胡同,似乎无法通过反复试验或阅读其他帖子找到答案.

This is my first post to the community, but I've been learning what I can by searching for about 2 weeks now. I seem to have hit a dead end that I can't seem to find the answer by trial and error or reading through others posts.

这时我要做的就是杀死Popen和shell本身创建的进程.我必须补充一点,我是编程新手,这是我的第一个真实"世界任务.

All I'm trying to do at this point is kill the process that is created by Popen and the shell itself. I must add that I am new to programming, and this is my first "real" world side task.

我见过的解决方案说创建一个组ID,但这是针对Unix的,我在Windows上. Popen.kill()和Popen.terminate()不会杀死shell的子级.由该代码启动的程序不会退出,它的PID与外壳程序的PID不同.我乐于接受建议,因为我既将其用作学习工具,又会有所作为.其他一些解决方案只是不会终止该过程.我可以通过DOS和Python解释器将其杀死,但是我必须从TASKLIST中手动查找PID,然后键入它.我需要从该程序中将其杀死.

The solutions I've seen say to create a group ID, but that is for Unix and I am on windows. Popen.kill() and Popen.terminate() do not kill the children of the shell. The program started by this code does not quit, it's PID is different then the PID of the shell. I am open to suggestions as I'm using this as both a learning tool and something that will be productive. Some of the other solutions just don't kill the process. I am able to kill it by DOS and the Python Interpreter, however I have to manually look up the PID from the TASKLIST and then type it in. I need to kill it from this program.

我正在构建此代码,以保存MathCad模板的多个文档,该模板读取excel文档的值,并使用新文件名吐出已保存的文档.提前致谢.请原谅您可能会看到的任何新手编码内容,因为我只是想弄湿自己.

I'm building this code to save multiple documents of a MathCad template that reads in values of excel documents, and spits out a saved document with the new file name. Thanks in advance. Please forgive any newbie coding things you may see as I'm just trying to get my feet wet.

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

Additional tasks tried and updates (2/26/2014):

尝试使用subprocess.call('TASKKILL ...)而不是subprocess.Popen杀死程序.它不会杀死shell创建的孩子.尝试将proc = subprocess.Popen('....'shell = True)替换为subprocess.call('....',shell = True),并且SendKeys函数不再起作用.使用kill_proc_tree函数和"EOFError:[WinError 10054]远程主机强行关闭了现有连接"弹出窗口,尝试了psutil函数.子程序仍然无法关闭.

Tried killing the programs using subprocess.call('TASKKILL ...) instead of subprocess.Popen. It does not kill the child created by the shell. Tried replacing proc = subprocess.Popen(' ....' shell=True ) with subprocess.call('....', shell=True) and the SendKeys functions no longer work. Tried the psutil function with the kill_proc_tree function and an "EOFError: [WinError 10054] An existing connection was forcibly closed by the remote host" pop up window. The child program still does not close.

如果我删除kill/terminate/close命令并只运行程序,则proc.pid与os.getpid()不同.如果我使用psutil.Process(proc.pid)-它表示Python解释器将返回其PID时该进程不存在.如果我得到MathCadPrime.exe PID =例如从TASKLIST中获取1111并使用psutil.Process(1111).parent,它不显示任何父项.这可能是为什么在shell上执行TASKKILL不会关闭子级的原因?我已经按照编写的代码发布了我的代码,以查看您的专家是否发现了我没有的东西.

If I remove the kill/terminate/close commands and just let the program run, the proc.pid is different than the os.getpid(). If I use the psutil.Process(proc.pid) - it says the process does not exist when the Python Interpreter will return its PID. If I get the MathCadPrime.exe PID = e.g. 1111 from TASKLIST and use psutil.Process(1111).parent, it shows no parents. This may be the reason why doing a TASKKILL on the shell doesn't close the children? I have posted my code exactly as I have it written to see if you gurus see something I don't.

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

推荐答案

感谢所有帮助人员,您帮助我得出了结论.与建议的略有不同,但是每次都能完成工作.我在家里,而不是在工作(所以我把这个写在脑海中),但基本上我所做的就是将TASKLIST写入一个文本文件,并只过滤出一串代码:

Thanks for all the help guys, you helped me come to a conclusion. Slightly different than suggested, but gets the job done every time. I'm at home, and not at work (so I'm writing this off the top of my head), but essentially all I did was write the TASKLIST to a text file and filter out just one string of code:

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)

我希望这可以对其他人有所帮助.

I hope this may help someone else.

这篇关于杀死Popen子进程的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆