Sie missverstehen, wie PdhLookupPerfNameByIndex() funktioniert. Seine Aufgabe ist es einen Leistungsindikator abzubilden, sondern eine Zeichenfolge abzubilden. Es sollte sowohl für die Kategorie des Counters als auch für seinen Namen verwendet werden. Nicht für die Instanz des Counters, falls zutreffend, ist sie nicht lokalisiert.
Der beste Weg, um zu sehen, was es ist, tut von Regedit.exe verwenden. Navigieren Sie zu HKEY_LOCAL_MACHINE \ SOFTWARE \ Microsoft \ Windows NT \ Currentversion \ Perflib. Beachten Sie den "009" Schlüssel, sein Counter-Wert hat den Index zu englischem Zeichenfolgenzuordnung. Doppelklicken Sie auf Counter und kopieren Sie den Inhalt der Box in einen Texteditor, um ihn besser sehen zu können. Der Schlüssel "CurrentLanguage" ist dasselbe Mapping, verwendet aber die lokalisierten Namen.
Damit PdhLookupPerfNameByIndex() den Schlüssel CurrentLanguage verwendet, verwenden Sie die Liste, die Sie im vorherigen Schritt erhalten haben, um die Indexnummer der Zeichenfolge zu kennen. Die andere Möglichkeit, es (wie zu vermerken) unten im KB-Artikel zu tun, besteht darin, zunächst die Indexnummer aus dem Registrierungsschlüssel "009" nachzuschlagen. Auf diese Weise können Sie von der englischen Zeichenfolge in die lokalisierte Zeichenfolge umwandeln. Beachten Sie, dass der KB-Artikel den Speicherort des Registrierungsschlüssels falsch dokumentiert, keine Ahnung warum. Beachten Sie, dass es weniger als perfekt ist, wie im KB-Artikel ausgeführt, diese Zuordnungen existieren nur für die "Basis" -Zähler und der "009" -Schlüssel ist mehrdeutig, da einige Indizes auf die gleiche Zeichenfolge abgebildet werden. Das Testen auf einer lokalisierten Windows-Version ist sehr wichtig.
einige Code, der es in beide Richtungen funktioniert:
using System;
using System.Collections.Generic;
using System.Text;
using Microsoft.Win32;
using System.Diagnostics;
using System.Runtime.InteropServices;
public static class PerfMapper {
private static Dictionary<string, int> English;
private static Dictionary<int, string> Localized;
public static PerformanceCounter FromEnglish(string category, string name, string instance = null) {
return new PerformanceCounter(Map(category), Map(name), instance);
}
public static PerformanceCounter FromIndices(int category, int name, string instance = null) {
return new PerformanceCounter(PdhMap(category), PdhMap(name), instance);
}
public static bool HasName(string name) {
if (English == null) LoadNames();
if (!English.ContainsKey(name)) return false;
var index = English[name];
return !Localized.ContainsKey(index);
}
public static string Map(string text) {
if (HasName(text)) return Localized[English[text]];
else return text;
}
private static string PdhMap(int index) {
int size = 0;
uint ret = PdhLookupPerfNameByIndex(null, index, null, ref size);
if (ret == 0x800007D2) {
var buffer = new StringBuilder(size);
ret = PdhLookupPerfNameByIndex(null, index, buffer, ref size);
if (ret == 0) return buffer.ToString();
}
throw new System.ComponentModel.Win32Exception((int)ret, "PDH lookup failed");
}
private static void LoadNames() {
string[] english;
string[] local;
// Retrieve English and localized strings
using (var hklm = RegistryKey.OpenBaseKey(RegistryHive.LocalMachine, RegistryView.Registry64)) {
using (var key = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009")) {
english = (string[])key.GetValue("Counter");
}
using (var key = hklm.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\CurrentLanguage")) {
local = (string[])key.GetValue("Counter");
}
}
// Create English lookup table
English = new Dictionary<string, int>(english.Length/2, StringComparer.InvariantCultureIgnoreCase);
for (int ix = 0; ix < english.Length - 1; ix += 2) {
int index = int.Parse(english[ix]);
if (!English.ContainsKey(english[ix + 1])) English.Add(english[ix + 1], index);
}
// Create localized lookup table
Localized = new Dictionary<int, string>(local.Length/2);
for (int ix = 0; ix < local.Length - 1; ix += 2) {
int index = int.Parse(local[ix]);
Localized.Add(index, local[ix + 1]);
}
}
[DllImport("pdh.dll", CharSet = CharSet.Auto)]
private static extern uint PdhLookupPerfNameByIndex(string machine, int index, StringBuilder buffer, ref int bufsize);
}
Verwendungsbeispiel:
class Program {
static void Main(string[] args) {
var ctr1 = PerfMapper.FromEnglish("Processor", "% Processor Time");
var ctr2 = PerfMapper.FromIndices(238, 6);
}
}
ich nur Zugriff auf eine englische Version von Windows haben so nicht für Genauigkeit auf einer lokalisierten Version bürgen . Bitte korrigieren Sie eventuelle Fehler, indem Sie diesen Beitrag bearbeiten.
Es scheint, dass die englischen Namen die meiste Zeit funktionieren (auch auf deutschen Systemen getestet). Aber wir hatten einige Schweizer Systeme, die diese englischen Zähler nicht finden konnten. – thomai