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

查看:46
本文介绍了替代 psutil.Process(pid).name的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我测量了 psutil.Process(pid).name 的性能,结果证明它比 psutil.Process(pid).exe 慢十倍以上.因为这些函数中的最后一个需要对路径具有不同的权限,所以我不能仅仅从路径中提取文件名.我的问题是: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. 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?

推荐答案

您提到这是针对 Windows 的.我查看了 psutil 对 windows 的作用.看起来 psutil.Process().name 正在使用 Windows 工具帮助 API.如果您查看 psutil 的 Process 代码并跟踪 .name,它会转到 process_info.c.它会遍历您系统上的所有 pid,直到找到您正在寻找的那个.我认为这可能是 toolhelp API 的一个限制.但这就是为什么它比 .exe 慢的原因,它使用不同的 API 路径(如您所指出的),需要额外的特权.

You mentioned this is for windows. I took a look at what psutil does for windows. It looks like psutil.Process().name is using the windows tool help API. If you look at psutil's Process code and trace .name, it goes to get_name() in process_info.c. It is looping through all the pids on your system until it finds the one you're looking for. I think this may be a limitation of the toolhelp API. But this is why it's slower than .exe, which uses a different API path, that (as you pointed out), requires additional privilege.

我想到的解决方案是使用ctypes和ctypes.windll直接调用windows ntapi.它只需要 PROCESS_QUERY_INFORMATION,这与 PROCESS_ALL_ACCESS 不同:

The solution I came up with is to use ctypes and ctypes.windll to call the windows ntapi directly. It only needs PROCESS_QUERY_INFORMATION, which is different than 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)

这篇关于替代 psutil.Process(pid).name的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆