Windows中的性能计数器名称是本地化的,因此例如计数器Processor(_Total)% Processor Time
在其他语言版本的Windows中被称为其他名称。这意味着为了找到正确的名称,必须首先找到计数器的索引,然后使用PdhLookupPerfNameByIndex函数来获得本地化的名称(如果Windows XP应该支持,使用pdhadddenglishcounter是无效的)。
这对于上面计数器路径的性能对象(Processor
)和计数器(% Processor Time
)部分都很好,但是实例名(_Total
)呢?我在注册表中找不到这个字符串,所以我认为它是由提供信息的任何系统组件提供的。
系统提供的性能计数器的实例名是否保证在不同语言版本的Windows中相同?
如果不是,我如何确定哪个实例对应于_Total
实例?
根据这个支持的知识库,只有对象和计数器有友好的名称:
但是,实例在每种语言中都没有一个用户友好的名称。
所以这让我相信给定计数器的实例名是动态获得的(例如进程的ProcessId)或静态获得的(例如硬编码)。当然,没有什么可以阻止某人在英语构建中硬编码"_Total",在德语构建中硬编码其他东西,尽管通常的做法似乎是将语言内容限制在注册表中,并通过索引处理对象和计数器,并通过动态或静态名称处理实例。我认为微软一直在使用"_Total",因为我在一些外语安装中看到过它。
Luke说得对。为了获得Processor(_Total)% Processor Time的本地化版本,我们必须获得路径"Processor"one_answers"%Processor Time"中每个组件的本地化名称,其中"(_Total)"为常量。索引可能因操作系统版本而异,因此您必须在每次运行时发现它们。win32pyutil模块包含将加载英语到索引映射但保留它的方法,并且由于它并不小,如果您只需要它一次,那么这可能是内存浪费。我们使用以下语句:
def _find_pdh_counter_localized_name(eng_names,machine_name=None):
'''
Create a map of english names to indexes. We then lookup the english
name in the map to get the localized name.
Shamefully lifted from win32pdhutil, only this one uses a transient map
instead of a persistent one.
Will throw KeyError if a name is asked for that is not in the list.
'''
import win32api, win32con
counter_reg_value = win32api.RegQueryValueEx(
win32con.HKEY_PERFORMANCE_DATA, "Counter 009"
)
counter_list = counter_reg_value[0]
eng_map={}
for i in range(0, len(counter_list) - 1, 2):
try:
counter_id = int(counter_list[i])
except ValueError:
continue
eng_map[counter_list[i+1].lower()] = counter_id
ret = []
for name in eng_names:
ret.append(win32pdh.LookupPerfNameByIndex(
machine_name, eng_map[name.lower()])
)
del eng_map
return tuple(ret)
构造计数器名称:
names = _find_pdh_counter_localized_name(['processor','% processor time'])
counter_name = r'%s(_Total)%s' % names
生成所需的值。例如,意大利语中的"Processore(_Total)% Tempo Processore"