Microsoft KB Archive/287159

{|
 * width="100%"|

INFO: Using PDH APIs Correctly in a Localized Language

 * }

Q287159

-

The information in this article applies to:


 * Microsoft Win32 Application Programming Interface (API), used with:
 * the operating system: Microsoft Windows 2000
 * the operating system: Microsoft Windows NT 4.0

-

SUMMARY
Performance Data Helper (PDH) APIs use object and counter names that are in the localized language. So, applications using PDH APIs should always use the localized string for the object or counter name specification. Before collecting performance data, the application must know the object or counter name in the application. If the name of the objects and counters is known only as an English string in the application, there are some additional steps that must be performed on a system that uses a localized language, such as French or German. This article explains the steps that are required.

MORE INFORMATION
Applications that retrieve object and counter names by using the PdhEnumObjects or PdhEnumObjectItems APIs will always have strings corresponding to the localized language. If the application is interested in collecting the performance data of all performance objects, counters, and instances, then it can use the names returned by the PdhEnumObjects or PdhEnumObjectItems API to construct a counter path in the localized language and then add the counter by using the PdhAddCounter API to a PDH query. If the performance data is collected in this manner, then the application will work correctly in each localized language.

However, there are situations in which an application is interested in collecting performance data of only a particular performance object, counter, and instance. In such cases, the application must know the localized language name in PDH API calls that take a name, such as PdhAddCounter. However, each of the objects and counters have different &quot;user-friendly&quot; names in each localized language. These user-friendly names are exposed by the respective performance extension DLL in an .ini file for each localized language. For example, objects have a user friendly name like &quot;Process&quot; in English. In German or French, the same object is represented by a user-friendly name in the corresponding language, and the name is not a string that is directly converted from ANSI to UNICODE. Likewise, the counter has a user-friendly name like &quot;% Processor Time&quot; in English. However, instances do not have a user friendly name in each language. In a non-English version of Windows NT or Windows 2000, object and counter strings are stored both in the native language of the system and in English. Each object or counter is identified by an object or counter index respectively. The object or counter index and name mapping information is stored in the Counter registry value under the following registry key:

HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\LangId

where LangId is 009 for US English. The Counter registry value is of type REG_MULTI_SZ and can be viewed only by using Regedt32. The index value for the base system counters and objects like processor, process, thread, memory, and so forth are always the same irrespective of the localized version of the operating system or service pack installed. However, the index value of objects returned by a performance extension DLL will be different on different systems. A performance extension can be installed on top of the base operating system by using the LODCTR.exe utility. LODCTR.exe generates indexes from the .ini file supplied to this utility. So, the index value for performance extension counter providers like Microsoft Internet Information Server, Microsoft SQL Server, and so forth, will be different from system to system, depending on installation sequence.

If the application knows the object and counter names only as English strings, these names can be converted to the corresponding localized names as follows.

Use the Registry API to obtain the counter titles and indexes in English as below:

dwStatus = RegQueryValueEx(  HKEY_PERFORMANCE_DATA,   &quot;Counter 009&quot;,    NULL,    &dwType,    lpmszCounters,   &cbCounters); The lpmszCounters buffer is filled with the multi-string value, including the object and counter names with the indexes. The &quot;009&quot; is for English. The format is index string followed by name string, and then index string followed by name string terminated by another NULL character at the end. The application can get this list once, which can be used to get the ID corresponding to an English object/counter string. Once the index for a performance object as well as counter has been identified, the application can find the localized object or counter name from the index by using the PdhLookupPerfNameByIndex API. The localized object and counter name returned by this API can then be used in other PDH API calls that take object or counter names. If the performance object or counter name is collected by using the PdhLookupPerfNameByIndex API, then the application will work correctly in each localized language.