3

WinXPx32 では問題なく動作する次のコードを使用しますが、Win7x64 では 0 を返します。psutil ライブラリもそれを返すことはわかっていますが、追加の依存関係なしで実行できるものが必要です。ctypes と win32api は問題ありません。Kernel32.K32GetProcessMemoryInfo も同じ結果で試しました。

import ctypes

psapi = ctypes.windll.psapi
Kernel32 = ctypes.windll.Kernel32

class PROCESS_MEMORY_COUNTERS_EX(ctypes.Structure):
    _fields_ = [("cb", ctypes.c_ulong),
                ("PageFaultCount", ctypes.c_ulong),
                ("PeakWorkingSetSize", ctypes.c_size_t),
                ("WorkingSetSize", ctypes.c_size_t),
                ("QuotaPeakPagedPoolUsage", ctypes.c_size_t),
                ("QuotaPagedPoolUsage", ctypes.c_size_t),
                ("QuotaPeakNonPagedPoolUsage", ctypes.c_size_t),
                ("QuotaNonPagedPoolUsage", ctypes.c_size_t),
                ("PagefileUsage", ctypes.c_size_t),
                ("PeakPagefileUsage", ctypes.c_size_t),
                ("PrivateUsage", ctypes.c_size_t),
                ]

def GetProcessPrivateUsage():
    mem_struct = PROCESS_MEMORY_COUNTERS_EX()
    p_handle = Kernel32.GetCurrentProcess()
    b = psapi.GetProcessMemoryInfo(p_handle, ctypes.byref(mem_struct), ctypes.sizeof(mem_struct))
    print(b)
    return mem_struct.PrivateUsage

print(GetProcessPrivateUsage())
4

2 に答える 2

0

MSDN の次のサンプルに基づいてコードを変更しました。

from __future__ import print_function
import ctypes

psapi = ctypes.windll.psapi
Kernel32 = ctypes.windll.Kernel32

PROCESS_QUERY_INFORMATION = 0x0400
PROCESS_VM_READ = 0x0010

class PROCESS_MEMORY_COUNTERS_EX(ctypes.Structure):
    _fields_ = [("cb", ctypes.c_ulong),
                ("PageFaultCount", ctypes.c_ulong),
                ("PeakWorkingSetSize", ctypes.c_size_t),
                ("WorkingSetSize", ctypes.c_size_t),
                ("QuotaPeakPagedPoolUsage", ctypes.c_size_t),
                ("QuotaPagedPoolUsage", ctypes.c_size_t),
                ("QuotaPeakNonPagedPoolUsage", ctypes.c_size_t),
                ("QuotaNonPagedPoolUsage", ctypes.c_size_t),
                ("PagefileUsage", ctypes.c_size_t),
                ("PeakPagefileUsage", ctypes.c_size_t),
                ("PrivateUsage", ctypes.c_size_t),
                ]

def GetProcessPrivateUsage():
    mem_struct = PROCESS_MEMORY_COUNTERS_EX()

    id = Kernel32.GetCurrentProcessId()
    print_output('GetCurrentProcessId: {}'.format(id))

    handle = Kernel32.OpenProcess(PROCESS_QUERY_INFORMATION | PROCESS_VM_READ, False, id)
    print_output('GetCurrentProcess: {}'.format(handle))

    b = psapi.GetProcessMemoryInfo(handle, ctypes.byref(mem_struct), ctypes.sizeof(mem_struct))

    print_output('GetProcessMemoryInfo: {}'.format(b))
    return mem_struct.PrivateUsage

def print_output(text):
    print('{}. {}'.format(text, ctypes.FormatError(Kernel32.GetLastError())))

usage = GetProcessPrivateUsage()
print_output('private usage: {}'.format(usage))

私の最善の推測は、によって返されたハンドルにはGetCurrentProcess()、Windows 7 のメモリ カウンターへのアクセス権がなくなったということです ( GetLastError()「無効なハンドル」が返されます)。

ctypes でPROCESS_QUERY_INFORMATIONandが見つからなかったので、ここで実際の値を調べて定数として挿入しました。PROCESS_VM_READ

また、関数を追加して、print_output()どのステップが失敗しているかを確認できるようにしました。

于 2012-07-26T14:55:03.240 に答える