获取与 Windows 中的任务管理器相同的进程详细信息

2023-12-13

我编写了一个程序来获取当前正在运行的进程的内存详细信息psutil在Python 3中。问题是我得到的值与Windows任务管理器中的值不同。具体来说,如何在Python中获取进程的私有工作集大小?


psutil 调用GetProcessMemoryInfo,这不会破坏私有内存与共享内存的工作集。要获取此信息,您可以使用 Windows性能计数器API。我在下面演示的另一种方法是直接计算共享页面的数量。QueryWorkingSet返回一个数组PSAPI_WORKING_SET_BLOCK条目(工作集中每页一个),您可以统计具有Shared字段集。您需要一个进程句柄,您可以通过调用以下任一方法来获取该句柄GetCurrentProcess or OpenProcess。要将页面转换为字节,请通过调用以下任一方法获取系统页面大小GetPerformanceInfo or GetSystemInfo.

这种方法的缺点是您需要PROCESS_VM_READ and PROCESS_QUERY_INFORMATION访问进程。如果当前用户是高级管理员,通常会启用SeDebugPrivilege绕过访问检查,但“受保护”进程除外。

from ctypes import *
from ctypes.wintypes import *
from collections import namedtuple

__all__ = ['query_working_set', 'working_set_size']

kernel32 = WinDLL('kernel32', use_last_error=True)
psapi = WinDLL('psapi', use_last_error=True)

PROCESS_VM_READ           = 0x0010
PROCESS_QUERY_INFORMATION = 0x0400

ERROR_ACCESS_DENIED = 0x0005
ERROR_BAD_LENGTH    = 0x0018

ULONG_PTR = WPARAM
SIZE_T = c_size_t

class PSAPI_WORKING_SET_BLOCK(Union):
    class _FLAGS(Structure):
        _fields_ = (('Protection',  ULONG_PTR,  5),
                    ('ShareCount',  ULONG_PTR,  3),
                    ('Shared',      ULONG_PTR,  1),
                    ('Reserved',    ULONG_PTR,  3),
                    ('VirtualPage', ULONG_PTR, 20))
    _anonymous_ = '_flags',
    _fields_ = (('Flags', ULONG_PTR),
                ('_flags', _FLAGS))

class PSAPI_WORKING_SET_INFORMATION(Structure):
    _fields_ = (('NumberOfEntries',  ULONG_PTR),
                ('_WorkingSetInfo', PSAPI_WORKING_SET_BLOCK * 1))
    @property
    def WorkingSetInfo(self):
        array_t = PSAPI_WORKING_SET_BLOCK * self.NumberOfEntries
        offset = PSAPI_WORKING_SET_INFORMATION._WorkingSetInfo.offset
        return array_t.from_buffer(self, offset)

PPSAPI_WORKING_SET_INFORMATION = POINTER(PSAPI_WORKING_SET_INFORMATION)

def errcheck_bool(result, func, args):
    if not result:
        raise WinError(get_last_error())
    return args

psapi.QueryWorkingSet.errcheck = errcheck_bool
psapi.QueryWorkingSet.argtypes = (
    HANDLE,                         # _In_  hProcess
    PPSAPI_WORKING_SET_INFORMATION, # _Out_ pv
    DWORD)                          # _In_  cb

kernel32.GetCurrentProcess.restype = HANDLE

kernel32.OpenProcess.errcheck = errcheck_bool
kernel32.OpenProcess.restype = HANDLE
kernel32.OpenProcess.argtypes = (
    DWORD, # _In_ dwDesiredAccess
    BOOL,  # _In_ bInheritHandle
    DWORD) # _In_ dwProcessId

def query_working_set(pid=None):
    """Return the PSAPI_WORKING_SET_BLOCK array for the target process."""
    if pid is None:
        hprocess = kernel32.GetCurrentProcess()
    else:
        access = PROCESS_VM_READ | PROCESS_QUERY_INFORMATION
        hprocess = kernel32.OpenProcess(access, False, pid)
    info = PSAPI_WORKING_SET_INFORMATION()
    base_size = sizeof(info)
    item_size = sizeof(PSAPI_WORKING_SET_BLOCK)
    overshoot = 0
    while True:
        overshoot += 4096
        n = info.NumberOfEntries + overshoot
        resize(info, base_size + n * item_size)
        try:
            psapi.QueryWorkingSet(hprocess, byref(info), sizeof(info))
            break
        except OSError as e:
            if e.winerror != ERROR_BAD_LENGTH:
                raise
    return info.WorkingSetInfo

class PERFORMANCE_INFORMATION(Structure):
    _fields_ = (('cb',                DWORD),
                ('CommitTotal',       SIZE_T),
                ('CommitLimit',       SIZE_T),
                ('CommitPeak',        SIZE_T),
                ('PhysicalTotal',     SIZE_T),
                ('PhysicalAvailable', SIZE_T),
                ('SystemCache',       SIZE_T),
                ('KernelTotal',       SIZE_T),
                ('KernelPaged',       SIZE_T),
                ('KernelNonpaged',    SIZE_T),
                ('PageSize',          SIZE_T),
                ('HandleCount',       DWORD),
                ('ProcessCount',      DWORD),
                ('ThreadCount',       DWORD))
    def __init__(self, *args, **kwds):
        super(PERFORMANCE_INFORMATION, self).__init__(*args, **kwds)
        self.cb = sizeof(self)

PPERFORMANCE_INFORMATION = POINTER(PERFORMANCE_INFORMATION)

psapi.GetPerformanceInfo.errcheck = errcheck_bool
psapi.GetPerformanceInfo.argtypes = (
    PPERFORMANCE_INFORMATION, # _Out_ pPerformanceInformation
    DWORD)                    # _In_  cb

WorkingSetSize = namedtuple('WorkingSetSize', 'total shared private')

def working_set_size(pid=None):
    """Return the total, shared, and private working set sizes
       for the target process.
    """
    wset = query_working_set(pid)
    pinfo = PERFORMANCE_INFORMATION()
    psapi.GetPerformanceInfo(byref(pinfo), sizeof(pinfo))
    pagesize = pinfo.PageSize        
    total = len(wset) * pagesize
    shared = sum(b.Shared for b in wset) * pagesize
    private = total - shared
    return WorkingSetSize(total, shared, private)

if __name__ == '__main__':
    import sys    
    pid = int(sys.argv[1]) if len(sys.argv) > 1 else None
    try:
        total, shared, private = working_set_size(pid)
    except OSError as e:
        if e.winerror == ERROR_ACCESS_DENIED:
            sys.exit('Access Denied')
        raise
    width = len(str(total))
    print('Working Set: %*d' % (width, total))
    print('     Shared: %*d' % (width, shared))
    print('    Private: %*d' % (width, private))

例如:

C:\>tasklist /fi "imagename eq explorer.exe"

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
explorer.exe                  2688 Console                    1     66,048 K

C:\>workingset.py 2688
Working Set: 67465216
     Shared: 59142144
    Private:  8323072

下面演示了即使作为管理员也被拒绝访问系统进程。通常启用SeDebugPrivilege解决这个问题(请注意,权限必须存在于进程令牌中才能启用它;您不能只向令牌添加权限)。显示如何在访问令牌中启用和禁用权限超出了本答案的范围,但下面我将证明它确实有效,至少对于不受保护的进程而言。

C:\>tasklist /fi "imagename eq winlogon.exe"

Image Name                     PID Session Name        Session#    Mem Usage
========================= ======== ================ =========== ============
winlogon.exe                   496 Console                    1      8,528 K

C:\>workingset.py 496
Access Denied

C:\>python
>>> from workingset import *
>>> from privilege import enable_privilege
>>> enable_privilege('SeDebugPrivilege')
>>> working_set_size(496)
WorkingSetSize(total=8732672, shared=8716288, private=16384)
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

获取与 Windows 中的任务管理器相同的进程详细信息 的相关文章

  • Pandas 中允许重复列

    我将一个大的 CSV 包含股票财务数据 文件分割成更小的块 CSV 文件的格式不同 像 Excel 数据透视表之类的东西 第一列的前几行包含一些标题 公司名称 ID 等在以下列中重复 因为一家公司有多个属性 而不是一家公司只有一栏 在前几行
  • 如何计算numpy数组中元素的频率?

    我有一个 3 D numpy 数组 其中包含重复的元素 counterTraj shape 13530 1 1 例如 counterTraj 包含这样的元素 我只显示了几个元素 array 136 129 130 103 102 101 我
  • Pandas 数据帧到 numpy 数组 [重复]

    这个问题在这里已经有答案了 我对 Python 很陌生 经验也很少 我已经设法通过复制 粘贴和替换我拥有的数据来使一些代码正常工作 但是我一直在寻找如何从数据框中选择数据 但无法理解这些示例并替换我自己的数据 总体目标 如果有人真的可以帮助
  • 为什么在 Python 2.4 中使用 Unicode 数据会出现 ASCII 编码错误,而在 2.7 中却不会?

    我有一个程序 当在 Python 2 7 中运行时 会生成正确的 Unicode 输出到标准输出 当在 Python 2 4 中运行时 我得到UnicodeEncodeError ascii codec can t encode chara
  • python suds SOAP 请求中的名称空间前缀错误

    我使用 python suds 来实现客户端 并且在发送的 SOAP 标头中得到了错误的命名空间前缀 用于定义由element ref 在 wsdl 中 wsdl 正在引用数据类型 xsd 文件 请参见下文 问题出在函数上GetRecord
  • 使用 OLS 回归预测未来值(Python、StatsModels、Pandas)

    我目前正在尝试在 Python 中实现 MLR 但不确定如何将我找到的系数应用于未来值 import pandas as pd import statsmodels formula api as sm import statsmodels
  • 如何通过在 Python 3.x 上按键来启动和中断循环

    我有这段代码 当按下 P 键时会中断循环 但除非我按下非 P 键 否则循环不会工作 def main openGame while True purchase imageGrab if a sum gt 1200 fleaButton ti
  • 在flatpak项目中使用scrapy脚本

    我正在构建一个 flatpak 构建的项目 我有一个按钮 当单击它时我希望它运行 scrapy 脚本来抓取数据 窗口用户界面
  • 如何将 Hudson/Jenkins 参数传递给 Windows 批处理命令

    好吧 我需要在我的 Hudson 作业中执行一个批处理文件 我有一个参数 Jenkis 参数 我需要将这个值 如参数 传递给批处理文件 我尝试了以下操作 Deploy cmd configuration DEPLOYCONFIGURATIO
  • 首先对列表中最长的项目进行排序

    我正在使用 lambda 来修改排序的行为 sorted list key lambda item item lower len item 对包含元素的列表进行排序A1 A2 A3 A B1 B2 B3 B 结果是A A1 A2 A3 B
  • 将 2D NumPy 数组按元素相乘并求和

    我想知道是否有一种更快的方法 专用 NumPy 函数来执行 2D NumPy 数组的元素乘法 然后对所有元素求和 我目前使用np sum np multiply A B 其中 A B 是相同维度的 NumPy 数组m x n 您可以使用np
  • python Soap zeep模块获取结果

    我从 SOAP API 得到如下结果 client zeep Client wsdl self wsdl transport transport auth header lb E authenticate self login res cl
  • 使用 Firefox 绕过弹出窗口下载文件:Selenium Python

    我正在使用 selenium 和 python 来从中下载某些文件web page http www oceanenergyireland com testfacility corkharbour observations 我之前一直使用设
  • 使用 PyTorch 分布式 NCCL 连接失败

    我正在尝试使用 torch distributed 将 PyTorch 张量从一台机器发送到另一台机器 dist init process group 函数正常工作 但是 dist broadcast 函数中出现连接失败 这是我在节点 0
  • Tkinter - 浮动窗口 - 调整大小

    灵感来自this https stackoverflow com a 22424245 13629335问题 我想为我的根窗口编写自己的调整大小函数 但我刚刚注意到我的代码显示了一些性能问题 如果你快速调整它的大小 你会发现窗口没有像我希望
  • 迭代 my_dict.keys() 并修改字典中的值是否会使迭代器失效?

    我的例子是这样的 for my key in my dict keys my dict my key mutate 上述代码的行为是否已定义 假设my dict是一本字典并且mutate是一个改变其对象的方法 我担心的是 改变字典中的值可能
  • Ubuntu 上的 Python 2.7

    我是 Python 新手 正在 Linux 机器 Ubuntu 10 10 上工作 它正在运行 python 2 6 但我想运行 2 7 因为它有我想使用的功能 有人敦促我不要安装 2 7 并将其设置为我的默认 python 我的问题是 如
  • 在Python中按属性获取对象列表中的索引

    我有具有属性 id 的对象列表 我想找到具有特定 id 的对象的索引 我写了这样的东西 index 1 for i in range len my list if my list i id specific id index i break
  • 从 Twitter API 2.0 获取 user.fields 时出现问题

    我想从 Twitter API 2 0 端点加载推文 并尝试获取标准字段 作者 文本 和一些扩展字段 尤其是 用户 字段 端点和参数的定义工作没有错误 在生成的 json 中 我只找到标准字段 但没有找到所需的 user fields 用户
  • 您可以使用关键字参数而不提供默认值吗?

    我习惯于在 Python 中使用这样的函数 方法定义 def my function arg1 None arg2 default do stuff here 如果我不供应arg1 or arg2 那么默认值None or default

随机推荐

  • 使用 Scala 中现有的列表列表创建 Breeze DenseMatrix

    I ve a List List Int List List 1 2 3 0 0 0 0 0 0 List 0 0 0 1 2 3 0 0 0 List 0 0 0 0 0 0 1 2 3 我想创建一个 3 行 9 列的 Matrix De
  • istio AuthorizationPolicy拒绝规则问题

    我定义了以下第一个策略来拒绝命名空间 foo 中对工作负载 1 的所有请求 除非它们来自工作负载 2 或工作负载 3 尝试从工作负载 2 访问工作负载 1 时 我收到 RBAC 访问被拒绝 但是 当使用如下所示的 ALLOW 策略重写它们时
  • Android:通过POST发送图像

    我一直在寻找解决方案 并遇到了多部分和不同的设置 但我似乎无法让它正常工作 这是我到目前为止所拥有的 编辑 我收到的服务器端错误是 500 我认为这是因为我发送的数据对于一个请求来说太大或者格式不正确 ByteArrayOutputStre
  • 将背景放在线性布局上并占据几乎 3/4 的屏幕

    我已经尝试了其他帖子的各种帮助 将宽度设置为 0dp 等 但似乎没有任何效果 我有两种布局 第一个似乎仍然占主导地位 如果我在文本视图上放置背景颜色 它们就会表现出自己的行为并正确结束 然而 在线性布局上放置一个背景 它几乎占了屏幕的 3
  • 使用 PHP 将 .key 文件从 DER 格式加载到 PEM

    我有一个进行转换的代码 但需要使用本机 PHP 函数来完成它 因为它没有激活对运行 exec 的支持 exec openssl pkcs8 inform DER in archivo key out archivo key pem pass
  • 如何轻松地在 pubspec.yaml 中添加 100 多个手动图像?

    我需要在我的应用程序中添加大量图像 并计划让应用程序保持离线状态 写 assets image1 jpg 让人心痛 我是flutter新手 不知道还有没有其他方法 有没有 要包含资产 flutter assets assets my ico
  • HTTP 缓存控制

    我正在为此苦苦挣扎 在 PHP 中 我为 GET AJAX 调用执行此操作 header Cache Control max age 10000 private 此后浏览器仍然能够发出请求吗 为什么 header Expires gmdat
  • 更改 AlertDialog 中超链接的颜色

    通常情况下 这种行为并不严重 但在 Samsung Galaxy S 上 默认的 AlertDialog 背景为蓝色 并且正常格式的链接 蓝色 消失 不幸的是 下面的代码不会改变链接的颜色 有人有想法吗 public void showCl
  • SQL 按日期分组,但也获取不带记录的日期

    有没有一种简单的方法可以做到GROUP BY DATE timestamp 包括一段时间内的所有日期 无论是否有与该日期相关的任何记录 基本上 我需要生成这样的报告 24 Dec 0 orders 23 Dec 10 orders 22 D
  • 以编程方式设置 CKEditor 对话框的位置

    我正在尝试找到一种方法 以便在打开新对话框时以编程方式设置 CKEditor 对话框的位置 位置部分的实际设置似乎很简单 但我似乎无法弄清楚如何捕获正在创建和显示的新 CKEditor 对话框的事件 我假设这将是类似的事情 CKEDITOR
  • 在 haskell 中按所选字符分割字符串

    我试图在每次选择字符时分割一个字符串 所以如果我收到 1 2 3 4 5 我选择的角色是 结果是一个列表 例如 1 2 3 4 5 我一直在浏览这里已经回答的问题 他们指出我使用splitOn 然而 当我尝试import Data List
  • 仅当用户选择时才使用 Inno Setup 下载文件

    问题 我想知道如何编写脚本来下载第二个 zip 文件 但最初在两个 zip 文件之间进行选择 下载 解压并删除 zip 文件 每个 zip 文件具有不同的名称 但内容与 zip 文件具有不同的名称 每个名称相同 无需重命名 这个问题有点类似
  • 由于内存限制,串行json_decode

    我有一个很大的 json 文件 7 3MB 我尝试对其进行 json decode 但由于内存限制而失败 致命错误 允许的内存大小 134217728 字节耗尽 有没有一种方法可以一次使用一个对象 节点串行解码 json 文件 我想理论上你
  • “no-ansi”选项不存在

    我正在尝试在 Windows 上创建 laravel 项目 但这个问题向我展示并且我尝试更新作曲家 php版本是8 0 6 作曲家版本是2 0 14 laravel 版本是 4 2 5 根据对此的评论Github问题这是最新版本的 Symf
  • 检查所选文件是否与 标记上的接受属性匹配

    我希望防止用户上传服务器会从包含最少 JavaScript 的页面拒绝的文件 最好不要添加任何严重的依赖项 例如纯粹为了解决这一问题的 jQuery 由于我不是针对旧用户 因此我使用浏览器的表单验证系统来检查用户是否选择了有效文件 但它似乎
  • PhoneGap (Cordova.js) 和 JQuery.Ajax 不能一起工作

    我已经使用 Phonegap Jquery 构建了一个针对 Andriod 4 12 的 html 页面 我的业务需求是使用 cordova js 的相机 API 拍照 然后将捕获的图片发布到 ASMX Web 服务 问题 当我添加对 Co
  • 半透明物体渲染顺序

    渲染半透明对象时 使用 glBlend 建议按 z 顺序从后到前对对象进行排序 From opengl 文档 在应用程序中使用深度缓冲时 您需要注意渲染图元的顺序 需要首先渲染完全不透明的图元 然后按从后到前的顺序渲染部分不透明的图元 如果
  • 在 iPhone 中创建二维码

    我看过一些示例代码 这些代码正在从文本创建二维码 下面是代码 我们也可以从其他数据 如图像 生成二维码吗 NSString code 1001012023034 Barcode barcode Barcode alloc init self
  • 在Java中为数字添加前导零? [复制]

    这个问题在这里已经有答案了 有没有更好的方法来获得这个结果 如果 num 的位数多于位数 则此函数会失败 并且我觉得它应该在库中的某个地方 例如 Integer toString x 3d 或其他东西 static String intTo
  • 获取与 Windows 中的任务管理器相同的进程详细信息

    我编写了一个程序来获取当前正在运行的进程的内存详细信息psutil在Python 3中 问题是我得到的值与Windows任务管理器中的值不同 具体来说 如何在Python中获取进程的私有工作集大小 psutil 调用GetProcessMe