C# PerformanceCounterCategory.GetCategories与PerformMon不一致

C# PerformanceCounterCategory.GetCategories与PerformMon不一致,c#,.net,performancecounter,perfmon,C#,.net,Performancecounter,Perfmon,好的,我基本上是想创建一个已安装性能计数器类别的列表,就像在PerfMon中得到的那样。我用这个 System.Diagnostics.PerformanceCounterCategory.GetCategories() 这似乎是可行的,直到你检查了清单,发现其中一些不见了。我发现丢失的第一个是ReadyBoost缓存。这是因为项目被设置为在“x86”上编译。将此更改为“任意CPU”修复了该问题 但是仍然有一些是缺失的,例如,其中一台测试机器有一个“授权管理器应用程序”类别(我的没有,而且似乎

好的,我基本上是想创建一个已安装性能计数器类别的列表,就像在PerfMon中得到的那样。我用这个

System.Diagnostics.PerformanceCounterCategory.GetCategories()
这似乎是可行的,直到你检查了清单,发现其中一些不见了。我发现丢失的第一个是ReadyBoost缓存。这是因为项目被设置为在“x86”上编译。将此更改为“任意CPU”修复了该问题

但是仍然有一些是缺失的,例如,其中一台测试机器有一个“授权管理器应用程序”类别(我的没有,而且似乎没有人知道为什么,或者它来自哪里)。然而,在该机器上,性能计数器类别显示在PerfMon中,但在调用
GetCategories()时不会显示
来自C#的方法

有人知道为什么吗?是否有更可靠的方法获取
性能计数器类别
?这是因为我在使用.Net吗?是否有一些本机API可以替代

编辑

对不起,我还是不明白。我编写这段代码也许是为了更好地说明这一点:

using System;
using System.Diagnostics;
using System.Linq;
using System.Text.RegularExpressions;
using Microsoft.Win32;

namespace PccHack
{
    class Program
    {
        private static readonly Regex Numeric = new Regex(@"^\d+$");
        static void Main(string[] args)
        {
            var pcc1 = PerformanceCounterCategory.GetCategories();
            Console.Out.WriteLine("Getting automatically from the microsoft framework gave {0} results.", pcc1.Count());
            string[] counters;
            using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009"))
            {
                counters = regKey.GetValue("Counter") as string[];
            }
            var pcc2 = counters.Where(counter => !Numeric.IsMatch(counter)).ToList();
            pcc2.Sort();
            Console.Out.WriteLine("Getting manually from the registry gave {0} results.", pcc2.Count());
            Console.In.ReadLine();
        }
    }
}
现在我得到3236个结果。因为它获取系统中的所有性能计数器。所以我想我需要做的就是过滤掉那些实际上是性能计数器的,只剩下类别。但是,PerformanceCounter似乎没有只使用名称的构造函数(因为这不是唯一的),也没有使用索引值的构造函数。我发现了一个名为Performance Data Helper的Win32 API,但它似乎也没有我想要的功能。所以如果我有一个性能计数器索引,我如何在C中获得该索引的PerformanceCounter类别?PerfMon做到了这一点,所以它一定是可能的。有没有办法解析索引“幻数”来找出哪个是哪个

编辑2

好的。所以这是在做我的头。最新版本的代码使用了建议的三种不同方法(.Net/Registry/PowerShell):

使用系统;
使用System.Collections.Generic;
使用系统诊断;
使用System.Linq;
运用系统反思;
使用Microsoft.Win32;
使用系统、管理、自动化;
名称空间PccHack
{
内部课程计划
{
私有静态void Main()
{
var counterMap=新字典();
使用(var regKey=Registry.LocalMachine.OpenSubKey(@“SOFTWARE\Microsoft\windowsnt\CurrentVersion\Perflib\009”))
{
var counter=regKey.GetValue(“计数器”)作为字符串[];
对于(变量i=0;io.CategoryName.ToList();
var pcc2=新列表();
//获取v1提供程序
使用(var regKey=Registry.LocalMachine.OpenSubKey(@“SYSTEM\CurrentControlSet\services”))
{
foreach(regKey.GetSubKeyNames()中的var subKeyName)
{
使用(var subKey=regKey.OpenSubKey(subKeyName))
{
如果(!subKey.GetSubKeyNames().包含(“性能”))继续;
使用(var perfKey=subKey.OpenSubKey(“性能”))
{
var blah=(字符串)perfKey.GetValue(“对象列表”);
if(blah!=null)
{
pcc2.AddRange(blah.Split('').Select(b=>counterMap[b]);
}
}
}
}
}
//获取v2提供程序
使用(var regKey=Registry.LocalMachine.OpenSubKey(@“SOFTWARE\Microsoft\windowsnt\CurrentVersion\Perflib\\u V2Providers”))
{
foreach(regKey.GetSubKeyNames()中的var subKeyName)
{
使用(var subKey=regKey.OpenSubKey(subKeyName))
{
foreach(subKey.GetSubKeyNames()中的变量perfKeyName)
{
使用(var perfKey=subKey.OpenSubKey(perfKeyName))
{
var blah=(字符串)perfKey.GetValue(“NeutralName”);
if(blah!=null)
{
pcc2.添加(废话);
}
}
}
}
}
}
var ps=PowerShell.Create();
ps.AddCommand(“获取计数器”).AddParameter(“列表集”,“*”);
var pcc3=ps.Invoke().Select(result=>result.Members[“CounterSetName”].Value.ToString()).ToList();
pcc1.Sort();
pcc2.Sort();
pcc3.Sort();
WriteLine(“从microsoft框架自动获取{0}个结果。”,pcc1.Count());
WriteLine(“从注册表手动获取得到{0}个结果。”,pcc2.Count());
Console.Out.WriteLine(“从PowerShell获取{0}个结果。”,pcc3.Count());
Console.In.ReadLine();
}
}
}
在我的机器上,我使用.Net framework得到138个,通过解析注册表得到117个,通过使用PowerShell得到157个(这是正确的答案)

但是,取决于安装了PowerShell/Windows SDK的用户,这并不是一个真正的选项

有人有什么想法吗?是否有一些绝密版本3性能计数器类别,隐藏在注册表的其他地方,我需要追踪?我不仅没有想法可以尝试,我也没有坏主意可以尝试。有任何秘密的命令行开关吗
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Reflection;
using Microsoft.Win32;
using System.Management.Automation;


namespace PccHack
{
    internal class Program
    {
        private static void Main()
        {
            var counterMap = new Dictionary<string, string>();
            using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\009"))
            {
                var counter = regKey.GetValue("Counter") as string[];
                for (var i = 0; i < counter.Count() - 1; i += 2)
                {
                    counterMap.Add(counter[i], counter[i + 1]);
                }
            }

            var pcc1 = PerformanceCounterCategory.GetCategories().Select(o => o.CategoryName).ToList();
            var pcc2 = new List<string>();
            // Get v1 providers
            using (var regKey = Registry.LocalMachine.OpenSubKey(@"SYSTEM\CurrentControlSet\services"))
            {
                foreach (var subKeyName in regKey.GetSubKeyNames())
                {
                    using (var subKey = regKey.OpenSubKey(subKeyName))
                    {
                        if (!subKey.GetSubKeyNames().Contains("Performance")) continue;
                        using (var perfKey = subKey.OpenSubKey("Performance"))
                        {
                            var blah = (string) perfKey.GetValue("Object List");
                            if (blah != null)
                            {
                                pcc2.AddRange(blah.Split(' ').Select(b => counterMap[b]));
                            }
                        }
                    }
                }
            }
            // Get v2 providers
            using (var regKey = Registry.LocalMachine.OpenSubKey(@"SOFTWARE\Microsoft\Windows NT\CurrentVersion\Perflib\_V2Providers"))
            {
                foreach (var subKeyName in regKey.GetSubKeyNames())
                {
                    using (var subKey = regKey.OpenSubKey(subKeyName))
                    {
                        foreach (var perfKeyName in subKey.GetSubKeyNames())
                        {
                            using (var perfKey = subKey.OpenSubKey(perfKeyName))
                            {
                                var blah = (string) perfKey.GetValue("NeutralName");
                                if (blah != null)
                                {
                                    pcc2.Add(blah);
                                }
                            }
                        }
                    }
                }
            }
            var ps = PowerShell.Create();

            ps.AddCommand("Get-Counter").AddParameter("listSet", "*");
            var pcc3 = ps.Invoke().Select(result => result.Members["CounterSetName"].Value.ToString()).ToList();

            pcc1.Sort();
            pcc2.Sort();
            pcc3.Sort();
            Console.Out.WriteLine("Getting automatically from the microsoft framework gave {0} results.", pcc1.Count());
            Console.Out.WriteLine("Getting manually from the registry gave {0} results.", pcc2.Count());
            Console.Out.WriteLine("Getting from PowerShell gave {0} results.", pcc3.Count());
            Console.In.ReadLine();
        }
    }
}
Debug.WriteLine((new PerformanceCounterCategory("BranchCache")).ReadCategory().Keys.Count);