首页 > 解决方案 > 如何让 win32pdhutil 用斜杠查询性能计数器?

问题描述

我正在尝试使用Python 中 pywin32 包中的win32pdhutil查询 Windows 性能计数器,但是每当计数器名称带有斜杠时,我都会遇到错误。

例如,此代码工作正常:

import win32pdhutil

query = win32pdhutil.GetPerformanceAttributes("Memory", "Available Bytes")

但是这段代码失败了:

import win32pdhutil

query = win32pdhutil.GetPerformanceAttributes("Memory", "Cache Faults/sec")

错误信息是:

Traceback (most recent call last):
  File "<path>\Python\Python38-32\lib\site-packages\win32\lib\win32pdhutil.py", line 61, in GetPerformanceAttributes
    type, val = win32pdh.GetFormattedCounterValue(hc, format)
pywintypes.error: (-1073738810, 'GetFormattedCounterValue', 'The data is not valid.')

我尝试了许多不同的计数器,只有在计数器名称中有斜杠时才会遇到这个问题。

我的原始代码使用 win32pdh.AddCounter 和 win32pdh.CollectQueryData 具有相同的问题,但上面的示例在一行中演示了它。

我在这里找到了一个类似的线程,但没有明显的解决方案。

标签: pythonwinapipywin32

解决方案


You need to wait for "cache faults/sec" to collect enough data, Here is an c++ sample on msdn for Performance Counters api:

Browsing Performance Counters

And in python, if I hard code(just for test) in GetPerformanceAttributes function in win32pdhutil.py as below:

def GetPerformanceAttributes(object, counter, instance = None, inum=-1,
                             format = win32pdh.PDH_FMT_LONG, machine=None):
    # NOTE: Many counters require 2 samples to give accurate results,
    # including "% Processor Time" (as by definition, at any instant, a
    # thread's CPU usage is either 0 or 100).  To read counters like this,
    # you should copy this function, but keep the counter open, and call
    # CollectQueryData() each time you need to know.
    # See http://support.microsoft.com/default.aspx?scid=kb;EN-US;q262938
    # and http://msdn.microsoft.com/library/en-us/dnperfmo/html/perfmonpt2.asp
    # My older explanation for this was that the "AddCounter" process forced
    # the CPU to 100%, but the above makes more sense :)
    path = win32pdh.MakeCounterPath( (machine,object,instance, None, inum,counter) )
    hq = win32pdh.OpenQuery()
    try:
        hc = win32pdh.AddCounter(hq, path)
        try:
            win32pdh.CollectQueryData(hq)
            time.sleep(1)
            win32pdh.CollectQueryData(hq)
            type, val = win32pdh.GetFormattedCounterValue(hc, format)
            return val
        finally:
            win32pdh.RemoveCounter(hc)
    finally:
        win32pdh.CloseQuery(hq)

Then "Cache Faults/sec" works for me, you could try to customize your own m_GetFormattedCounterValue function, and then give the collector enough time to collect data like the sample above.


推荐阅读