简体   繁体   English

psutil.Process(pid).name 的替代品

[英]Alternative to psutil.Process(pid).name

I have measured the performance of psutil.Process(pid).name and it turns out that it is more than ten times slower than for example psutil.Process(pid).exe .我测量了psutil.Process(pid).name的性能,结果发现它比例如psutil.Process(pid).exe慢十倍以上。 Because the last one of these functions requires different privileges over the path, I cannot just just extract the filename from the path.因为这些函数中的最后一个需要对路径的不同权限,所以我不能只从路径中提取文件名。 My question is: Are there any alternatives to psutil.Process(pid).name , which does the same?我的问题是:是否有任何替代psutil.Process(pid).name的替代方法?

You mentioned this is for windows.您提到这是针对 windows 的。 I took a look at what psutil does for windows.我看了一下 psutil 对 windows 的作用。 It looks like psutil.Process().name is using the windows tool help API.看起来 psutil.Process().name 正在使用 windows 工具帮助 API。 If you look at psutil's Process code and trace.name, it goes to get_name() in process_info.c .如果您查看 psutil 的 Process code 和 trace.name,它会转到process_info.c中的 get_name()。 It is looping through all the pids on your system until it finds the one you're looking for.它循环遍历系统上的所有 pid,直到找到您正在寻找的那个。 I think this may be a limitation of the toolhelp API.我认为这可能是工具帮助 API 的限制。 But this is why it's slower than.exe, which uses a different API path, that (as you pointed out), requires additional privilege.但这就是为什么它比.exe 慢的原因,它使用不同的 API 路径,(正如您所指出的)需要额外的权限。

The solution I came up with is to use ctypes and ctypes.windll to call the windows ntapi directly.我想出的解决方案是使用 ctypes 和 ctypes.windll 直接调用 windows ntapi。 It only needs PROCESS_QUERY_INFORMATION, which is different than PROCESS_ALL_ACCESS:它只需要 PROCESS_QUERY_INFORMATION,这与 PROCESS_ALL_ACCESS 不同:

import ctypes
import os.path

# duplicate the UNICODE_STRING structure from the windows API

class UNICODE_STRING(ctypes.Structure):
    _fields_ = [
      ('Length', ctypes.c_short),
      ('MaximumLength', ctypes.c_short),
      ('Buffer', ctypes.c_wchar_p)
    ]

# args

pid = 8000 # put your pid here

# define some constants; from windows API reference

MAX_TOTAL_PATH_CHARS = 32767
PROCESS_QUERY_INFORMATION = 0x0400 
PROCESS_IMAGE_FILE_NAME = 27

# open handles

ntdll = ctypes.windll.LoadLibrary('ntdll.dll')
process = ctypes.windll.kernel32.OpenProcess(PROCESS_QUERY_INFORMATION,
  False, pid)

# allocate memory

buflen = (((MAX_TOTAL_PATH_CHARS + 1) * ctypes.sizeof(ctypes.c_wchar)) +
  ctypes.sizeof(UNICODE_STRING))
buffer = ctypes.c_char_p(' ' * buflen) 

# query process image filename and parse for process "name"

ntdll.NtQueryInformationProcess(process, PROCESS_IMAGE_FILE_NAME, buffer,
  buflen, None)
pustr = ctypes.cast(buffer, ctypes.POINTER(UNICODE_STRING))
print os.path.split(pustr.contents.Buffer)[-1]

# cleanup

ctypes.windll.kernel32.CloseHandle(process)
ctypes.windll.kernel32.FreeLibrary(ntdll._handle)

As of psutil 1.1.0 this problem has been fixed, see https://code.google.com/p/psutil/issues/detail?id=426从 psutil 1.1.0 开始,此问题已得到修复,请参阅https://code.google.com/p/psutil/issues/detail?id=426

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

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