带说明的tasklist命令

2024-09-29 06:26:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在尝试找出一个tasklist命令,该命令将给出Description,并显示在taskmanger UI中?我试着从python运行它,如果它不可行,是否有一个等价的python命令来获取所有任务的描述列表?在

tasklist /?

Tags: 命令ui列表description等价tasklisttaskmanger
1条回答
网友
1楼 · 发布于 2024-09-29 06:26:24

这比你想象的要复杂一点,你真的需要一个很好的理由去经历所有的麻烦来证明它的合理性。首先,任务管理器UI不会从tasklist.exe获取其信息,尽管您可以通过以下方式获得:

import csv
import subprocess

try:
    tl_out = subprocess.check_output(["tasklist", "/fo", "csv", "/v"])
except subprocess.CalledProcessError as e:
    print("Call to `tasklist` failed: {}".format(e))
    exit(1)

tl_csv = csv.DictReader(tl_out.splitlines())
for row in tl_csv:
    print(row)  # prints a dict for each task with all available fields
    # Available fields (may vary from platform to platform) are:
    # 'Status', 'CPU Time', 'Image Name', 'Session Name', 'Window Title',
    # 'PID', 'User Name', 'Session#', 'Mem Usage'

但是,要想访问Description字段(以及任务管理器UI中的许多其他字段),至少必须从WMI中提取数据。更糟糕的是,WMIC上的Windows 7 has a bug when exporting to CSV使得整个过程更加复杂,为了最大限度地提高可移植性,我们需要使用list格式并自己解析:

^{pr2}$

Python3的代码更新(使用encode进行字节搜索):

s1 = "\r\r\n\r\r\n".encode()
s2 = "\r\r\n".encode()
for task in wmi_out.strip().split(s1):
   wmi_entries.append(dict(e.split("=".encode(), 1) for e in task.strip().split(s2)))

如果您不需要所有这些字段,您可以始终限制wmic来获得您想要的字段(即wmi_out = subprocess.check_output(["wmic", "process", "get", "ProcessId,ExecutablePath,Description", "/format:list"])只获得DescriptionProcessId)。在

但别以为你的麻烦结束了-我们才刚刚开始。虽然我们现在有了Description字段(还有一些其他要启动的字段),但是您会注意到,对于那些没有声明其描述的进程(大多数进程,Windows程序员显然很懒)或没有描述的服务,description值只包含可执行文件的名称,例如,如果您运行的是普通的旧记事本,虽然任务管理器UI将向您显示Notepad作为说明,但它的字典条目将具有notepad.exe-这是因为任务管理器UI对任务列表使用了完全不同的方法,并直接从流程可执行文件中获取描述。在

因此,您实际上需要一个额外的步骤来直接从其资源表中检索可执行描述,这可能是通过调用Win32 API来获取描述的“最简单”方法,因此您需要首先安装pyWin32模块:

import subprocess
import win32api

# gets executable description via W32API
def get_executable_desc(path, default=''):
    try:
        language, codepage = win32api.GetFileVersionInfo(path, "\\VarFileInfo\\Translation")[0]
        return win32api.GetFileVersionInfo(path, "\\StringFileInfo\\{:04x}{:04x}\\FileDescription".format(language, codepage)) or default
    except:
        return default

try:
    wmi_out = subprocess.check_output(["wmic", "process", "list", "full", "/format:list"])
except subprocess.CalledProcessError as e:
    print("Call to `tasklist` failed: {}".format(e))
    exit(1)

# parse the WMI list:
wmi_entries = []
for task in wmi_out.strip().split("\r\r\n\r\r\n"):
    entry = dict(e.split("=", 1) for e in task.strip().split("\r\r\n"))
    entry['Description'] = get_executable_desc(entry.get("ExecutablePath", None), entry.get("Description", None))
    wmi_entries.append(entry)

for row in wmi_entries:
    print(row)  # prints a dict for each task with all available fields

瞧!现在已经填充了描述(如果可用,或者至少保存可执行文件名),但是由于我们必须使用Win32 API来获取描述,我们还可以通过它获得任务列表-它更快、更简洁:

from win32api import GetFileVersionInfo, OpenProcess
from win32con import PROCESS_QUERY_INFORMATION, PROCESS_VM_READ
from win32process import EnumProcesses, EnumProcessModules, GetModuleFileNameEx
import pywintypes

# gets executable description via W32API
def get_executable_desc(path, default=''):
    try:
        language, codepage = GetFileVersionInfo(path, "\\VarFileInfo\\Translation")[0]
        return GetFileVersionInfo(path, "\\StringFileInfo\\{:04x}{:04x}\\FileDescription".format(language, codepage)) or default
    except:
        return default

# gets the process list via W32API        
def get_process_list():
    proc_list = []
    processes = EnumProcesses()
    if not processes:
        return []  # optionally raise an exception, no ProcessIds could be obtained
    for proc in processes:
        try:
            handle = OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, pywintypes.FALSE, proc)
            modules = EnumProcessModules(handle)
            if not modules:
                continue  # task died in the meantime?
            path = GetModuleFileNameEx(handle, modules[0])
            proc_list.append({"ProcessId": proc, "ExecutablePath": path, "Description": get_executable_desc(path, path)})
        except pywintypes.error as e:
            continue  # optionally report the error stored in `e`
    return proc_list

tasks = get_process_list()
for row in tasks:
    print(row)  # prints a dict for each task with ProcessId, ExecutablePath and Description fields

这将只获得ProcessId、ExecutablePath和Description,但是如果需要更多字段,可以进一步探索win32api。在

同样,我不知道Description字段要经历所有这些麻烦的值是什么,但是如果您真的非常想要它-这就是如何获得它的方法。在

相关问题 更多 >