如何在任务管理器中知道正在运行的Python脚本?

6

在任务管理器中,我只能看到Python/Pythonwin的进程。那么我该如何找出哪个Python脚本正在运行?


实际上,Windows Vista和7已经带有一个任务管理器,可以显示完整的命令行。 - 0xC0000022L
哇,没想到!发现了它,打开它就很容易了。 - kindall
3个回答

13

通常回答这类问题的方法是使用Process Explorer。您可以在工具提示中看到任何python.exepythonw.exe实例的完整命令行。

要在Python中获取相同的信息,您可以使用psutil模块

import psutil

pythons = [[" ".join(p.cmdline), p.pid] for p in psutil.process_iter() 
            if p.name.lower() in ("python.exe", "pythonw.exe")]

结果pythons是表示Python进程的列表嵌套列表。每个子列表的第一项是启动该进程的命令行,包括任何选项。第二项是进程ID。

如果你想获得psutil Process类中的所有内容,可以使用以下代码:

pythons = [p for p in psutil.process_iter() if p.name.lower() in ("python.exe", "pythonw.exe")]

现在,在我的系统上,使用psutil.process_iter()迭代所有进程需要几秒钟的时间,这对我来说似乎是荒谬的。下面的方法显著更快,因为它在 Python 看到进程之前就进行了进程过滤,但它依赖于 wmic 命令行工具,而不是所有版本的 Windows 都有(尤其是 XP Home 版本缺少该工具)。此处的结果与第一个 psutil 版本相同(每个包含一个 Python 进程的命令行和进程 ID 的列表)。

import subprocess

wmic_cmd = """wmic process where "name='python.exe' or name='pythonw.exe'" get commandline,processid"""
wmic_prc = subprocess.Popen(wmic_cmd, stdout=subprocess.PIPE, stderr=subprocess.PIPE, shell=True)
wmic_out, wmic_err = wmic_prc.communicate()
pythons = [item.rsplit(None, 1) for item in wmic_out.splitlines() if item][1:]
pythons = [[cmdline, int(pid)] for [cmdline, pid] in pythons]
如果wmic不可用,则会得到一个空列表[]。由于您知道至少有一个Python进程(即您自己!),因此可以将其捕获为错误并显示适当的消息。
要获取自己的进程ID,以便在开始杀死进程等操作时可以将其排除在考虑之外,请尝试使用pywin32的win32process.GetCurrentProcessID()

有没有更好的方法在第二个Python进程中实现? - TankorSmash
我查看了pywin32,但没有找到任何有帮助的内容。我能想到的最好的方法是使用wmic来外壳调用。我已经添加了相应的代码。 - kindall
@TankorSmash:提出了一种替代方案,除了使用wmic命令行工具外,还使用了psutil - kindall
我在你的回答顶部看到了,对于额外的努力表示感谢! - TankorSmash
1
psutil 方法给了我 "AttributeError: 'function' object has no attribute 'lower'" 错误,但是使用 wmic 选项可以解决。 - craq
使用 p.name() 而不是 p.name -- p.name 是一个方法,而 p.name() 是一个属性。 - Donald Li

0

我在处理kindall的答案时遇到了一些问题。使用Python 3.8:

import psutil
for p in psutil.process_iter():
    try: 
        if p.name().lower() in ["python.exe", "pythonw.exe"]:
            print(p.pid, p.cmdline)
    except: 
        continue

-1

使用Python 3:

import psutil

pythons = [[" ".join(p.cmdline()), p.pid] for p in psutil.process_iter()
        if p.name().lower() in ["python.exe", "pythonw.exe"]]

1
@kindall 给出了相同的答案。 - marcolz

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接