【问题标题】:Retrieve performance counter value in a language-independent way以与语言无关的方式检索性能计数器值
【发布时间】:2011-07-31 17:04:49
【问题描述】:

在 Windows 下,性能计数器有不同的名称,具体取决于操作系统语言。例如,在英文 Windows 版本上,有性能计数器 \Processor(_Total)\% Processor Time。在德语 Windows 版本上,同一个计数器称为 \Prozessor(_Total)\Prozessorzeit (%)

是否有任何方法可以以独立于语言的方式(使用 C++ 或 C#)检索性能计数器值?或者有没有其他方法可以在没有性能计数器的情况下获得整台计算机的处理器负载?

【问题讨论】:

  • 您是否尝试过在德国机器上的代码中使用英文名称?
  • 是的,我已经尝试过了,但我收到了找不到计数器的错误消息。

标签: c# c++ windows performancecounter


【解决方案1】:

有 WinAPI 函数,QueryHighPerformanceCounterQueryHighPerformanceFrequency

【讨论】:

  • 其实名字里没有“高”!
  • 这些函数返回用于性能计数器的高精度计时器的值。但是您不能使用这些函数来返回性能计数器的值,例如 \Processor(_Total)\% Processor Time。
【解决方案2】:

您是否尝试过使用 Pdh 辅助函数和 PdhAddEnglishCounter 函数?

【讨论】:

  • 很遗憾,此功能仅适用于 Vista、Windows Server 2008 及更高版本。我还需要检索 Windows XP 和 Windows Server 2003 上的性能计数器。
【解决方案3】:

每个 PerfMon 计数器都有一个唯一的(每台机器)整数 ID 来标识 PerfMon 计数器(但是在标准计数器的情况下,此 ID 保证保持不变)。

将 PerfMon 计数器 ID 与其美国英文名称和本地化名称相关联的信息存储在注册表中的以下键中:

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

一旦您使用注册表获取 PerfMon 计数器名称(您可以将其作为标准计数器的常量嵌入到您的应用中),您可以使用 PdhLookupPerfNameByIndex 函数查找给定计数器 ID 的本地化名称。

更多详情请见Using PDH APIs correctly in a localized language (Microsoft KB)

您可能还会发现 Finding perfmon counter id via winreg (StackOverflow) 有点相关。

【讨论】:

  • 我比较了 ID,其中一些在其他计算机上有所不同。但是有一个解决方法:我使用英文名称在“009”键中查找 ID,然后使用 PdhLookupPerfNameByIndex 函数查找本地化名称。源代码:wojciechkulik.pl/csharp/…
【解决方案4】:

添加这个

using System.Runtime.InteropServices;
using Microsoft.Win32;

在你的类中导入 DLL(我的类名为 Program)

[DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Unicode)]
        static extern UInt32 PdhLookupPerfIndexByName(string szMachineName, string szNameBuffer, ref uint pdwIndex);

以您的操作系统语言发送您想要的计数器的名称,它会返回英文名称

public string GetEnglishName(string name)
        {
            string buffer2 = name;
            UInt32 iRet2 = new UInt32();
            iRet3 = PdhLookupPerfIndexByName(null, buffer2, ref iRet2);
            //Console.WriteLine(iRet2.ToString());

            RegistryKey pRegKey = Registry.LocalMachine;
            pRegKey = pRegKey.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009");
            string[] after;
            after = (string[])pRegKey.GetValue("Counter");
            string value = iRet2.ToString();
            int pos = Array.IndexOf(after, value);
            return after[pos + 1];
        }

这里是如何使用它

Program m = new Program();
            string result = m.GetEnglishName("Mémoire");
            Console.WriteLine(result);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2020-04-21
    • 1970-01-01
    • 1970-01-01
    • 2021-12-31
    • 1970-01-01
    • 1970-01-01
    • 2023-01-18
    • 2011-03-06
    相关资源
    最近更新 更多