我试图找出一个tasklist
命令给出Description
以及Taskmangaer UI中显示的内容?我试图从python中运行它,如果它不可用那么是否有等效的python命令获取具有描述的所有任务的列表?
tasklist /?
答案 0 :(得分:1)
这比你想象的要复杂一些,你真的需要一个很好的理由来解决所有问题。首先,任务管理器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中提取数据。更糟糕的是,Windows 7 has a bug when exporting to CSV WMIC
使整个事情变得更加复杂,因为我们需要使用list
格式并自行解析:
import subprocess
try:
wmi_out = subprocess.check_output(["wmic", "process", "list", "full", "/format:list"])
except subprocess.CalledProcessError as e:
print("Call to `wmic` failed: {}".format(e))
exit(1)
# parse the WMI list:
wmi_entries = []
for task in wmi_out.strip().split("\r\r\n\r\r\n"):
wmi_entries.append(dict(e.split("=", 1) for e in task.strip().split("\r\r\n")))
for row in wmi_entries:
print(row) # prints a dict for each task with all available fields
# Available fields (may vary from platform to platform) are:
# 'CSName', 'CommandLine', 'Description', 'ExecutablePath', 'ExecutionState', 'Handle',
# 'HandleCount', 'InstallDate', 'KernelModeTime', 'MaximumWorkingSetSize',
# 'MinimumWorkingSetSize', 'Name', 'OSName', 'OtherOperationCount', 'OtherTransferCount',
# 'PageFaults', 'PageFileUsage', 'ParentProcessId', 'PeakPageFileUsage',
# 'PeakVirtualSize', 'PeakWorkingSetSize', 'Priority', 'PrivatePageCount', 'ProcessId',
# 'QuotaNonPagedPoolUsage', 'QuotaPagedPoolUsage', 'QuotaPeakNonPagedPoolUsage',
# 'QuotaPeakPagedPoolUsage', 'ReadOperationCount', 'ReadTransferCount', 'SessionId',
# 'Status', 'TerminationDate', 'ThreadCount', 'UserModeTime', 'VirtualSize',
# 'WindowsVersion', 'WorkingSetSize', 'WriteOperationCount', 'WriteTransferCount'
如果您不需要所有这些字段,则可以随时限制wmic
为您提供所需的字段(即wmi_out = subprocess.check_output(["wmic", "process", "get", "ProcessId,ExecutablePath,Description", "/format:list"])
每Description
只获得ProcessId
)。
但不要以为你的烦恼已经结束 - 我们刚开始。虽然我们现在有Description
字段(还有一些其他字段用于引导),但您会注意到对于那些不公布其描述的进程(大多数情况下,Windows程序员显然是懒惰的)或没有描述的服务 - 描述值只包含可执行文件名,即如果您正在运行普通的旧记事本,而任务管理器UI将显示Notepad
作为描述,其字典条目将具有notepad.exe
- 这是因为任务管理器UI使用完全不同的任务列表方法,直接从流程可执行文件中获取描述。
因此,您实际上需要一个额外的步骤来直接从其资源表中检索可执行文件描述,这可能是通过调用Win32 API来获取描述所做的“最简单”,因此您需要安装{{3首先是模块:
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
Voilà!现在已经填充了描述(如果可用,或至少保存可执行文件名称),但由于我们必须使用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,但如果您需要更多字段,可以进一步探索Win32 API。
同样,我没有看到Description
字段有什么价值可以解决所有这些麻烦,但如果你真的,真的想要它 - 这就是如何获得它。