Альтернатива psutil.Process (pid) .name - PullRequest
3 голосов
/ 05 июля 2011

Я измерил производительность psutil.Process(pid).name, и оказалось, что она более чем в десять раз медленнее, чем, например, psutil.Process(pid).exe.Поскольку последняя из этих функций требует разных прав доступа к пути, я не могу просто извлечь имя файла из пути.Мой вопрос: есть ли альтернативы psutil.Process(pid).name, который делает то же самое?

Ответы [ 2 ]

4 голосов
/ 18 августа 2011

Вы упомянули, что это для окон.Я посмотрел на то, что psutil делает для Windows.Похоже, psutil.Process (). Name использует API справки инструмента Windows.Если вы посмотрите на код процесса psutil и отследите .name, он перейдет к get_name () в process_info.c .Он просматривает все pids в вашей системе, пока не найдет тот, который вы ищете.Я думаю, что это может быть ограничением API всплывающей подсказки.Но именно поэтому он медленнее, чем .exe, который использует другой путь API, который (как вы указали) требует дополнительных привилегий.

Решение, которое я придумал, заключается в использовании ctypes и ctypes.windll длявызовите окна нтапи напрямую.Требуется только 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)
0 голосов
/ 28 сентября 2013

Начиная с psutil 1.1.0 эта проблема была исправлена, см. https://code.google.com/p/psutil/issues/detail?id=426

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...