Windows中的性能计数器名称是本地化的,因此,例如,在其他语言版本的Windows中,计数器\Processor(_Total)\% Processor Time
被称为别的东西。 这意味着为了find正确的名字,首先必须find计数器的索引,然后使用PdhLookupPerfNameByIndex函数来获取本地化名称(如果应该支持Windows XP,则使用PdhAddEnglishCounter )。
这对于上面的计数器path的性能对象( Processor
)和计数器( % Processor Time
)部分来说都是好的,但是实例名称( _Total
)呢? 我无法在registry中find此string,所以我认为它是由提供信息的任何系统组件提供的。
系统提供的性能计数器的实例名称是否保证在不同语言版本的Windows中相同?
如果没有,我怎么能确定哪个实例对应_Total
实例?
根据这个支持KB ,只有对象和计数器有友好的名字:
但是,实例在每种语言中都没有用户友好的名称。
因此,这使我相信给定计数器的实例名称是动态获取的(例如ProcessId进程)或静态获取(例如硬编码)。 当然,没有什么能够阻止某人在英文版本中对“_Total”进行硬编码,而在德文版本中则是其他的东西,尽管通常的做法是将语言限制在注册表中,并通过以下方式处理对象和计数器:索引和动态或静态名称的实例。 我认为微软一贯使用“_Total”,因为我已经在一些外语安装上看到了它。
卢克是正确的。 为了获得处理器(_Total)\%处理器时间的本地化版本,我们必须获得路径“处理器”和“处理器时间百分比”的每个组件的本地化名称,其中'(_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”。