开发者

Are instance names for system performance counters localized?

Performance counter names in Windows are localized, so for instance the counter \Processor(_Total)\% Processor Time is called something else in other language versions of Windows. This means that in order to find the correct name one must first find the index of the counter and then use the PdhLookupPerfNameByIndex function to get the localized name (using PdhAddEnglishCounter is out if Windows XP should be supported).

This is all good for the performance object (Processor) and counter (% Processor 开发者_Go百科Time) parts of the counter path above, but what about the instance name (_Total)? I cannot find this string in the registry, so I suppose that it is provided by whatever system component that provides the information.

Is the instance name for system provided performance counters guaranteed to be the same across different language versions of Windows?

If not, how can I determine which instance corresponds to the _Total instance?


According to this support KB, only the objects and counters have friendly names:

However, instances do not have a user friendly name in each language.

So this leads me to believe that instance names for a given counter are obtained either dynamically (e.g. ProcessId for a process) or statically (e.g. hard-coded). Of course there is nothing stopping somebody from hard-coding "_Total" in an English build and something else in a German build, though it seems the common practice is to keep the language stuff confined to the registry and deal with the objects and counters by index and the instances by dynamic or static names. I think Microsoft consistently uses "_Total" as I've seen it on a few foreign language installs.


Luke is correct. In order to get the localized version of Processor(_Total)\% Processor Time, we have to get the localized names of each of the components of the path "Processor" and "%Processor Time" with the '(_Total)' being constant. The indexes can vary across OS versions, so you have to discover them on each run. The win32pyutil module contains methods that will load the english-to-index map but retains it, and since it's not small if you only need it once then that can be a memory waster. We use the following:

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)

To construct the counter name:

    names = _find_pdh_counter_localized_name(['processor','% processor time'])
    counter_name = r'\%s(_Total)\%s' % names

which yields the desired value. e.g., "\Processore(_Total)\% Tempo Processore" in Italian.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜