繁体   English   中英

杀死Popen子进程

[英]Kill the Popen child process

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

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

我见过的解决方案说可以创建一个组ID,但这是针对Unix的,并且我在Windows上。 Popen.kill()和Popen.terminate()不会杀死shell的子级。 由该代码启动的程序不会退出,它的PID与外壳程序的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时该进程不存在。 如果我从TASKLIST获取MathCadPrime.exe PID =例如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)

感谢所有帮助人员,您帮助我得出了结论。 与建议的略有不同,但是每次都能完成工作。 我在家里,而不是在工作(所以我把这个写在脑海中),但是基本上我所做的就是将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)

我希望这可以帮助其他人。

我尝试了以下代码,它为我工作:

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响应该事件。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM