【发布时间】:2014-03-28 02:51:23
【问题描述】:
这是我第一次在社区发帖,但我通过搜索大约 2 周的时间一直在学习我能做的事情。我似乎陷入了死胡同,我似乎无法通过反复试验或阅读其他帖子找到答案。
此时我要做的就是终止由 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 函数的 psutil 函数和“EOFError:[WinError 10054] 现有连接被远程主机强制关闭”弹出窗口。子程序仍然没有关闭。
如果我删除 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)
【问题讨论】:
-
你有read the docs吗?
-
是的。 Popen.kill() 和 Popen.terminate() 不会杀死 shell 的孩子。这段代码启动的程序并没有退出,它的PID和shell的PID不同。
-
好的,谢谢你的澄清
-
你想杀死整个进程树:shell、它的子进程等等?您当前的代码有什么问题?
-
尝试将 /t 添加到 taskkill,这应该也会杀死被杀死进程的所有子进程。