Source/Tx.Windows/PerfCounters/PdhUtils.cs (203 lines of code) (raw):

// Copyright (c) Microsoft Open Technologies, Inc. All rights reserved. See License.txt in the project root for license information. using System; using System.Collections.Generic; using System.Text; namespace Tx.Windows { internal static class PdhUtils { public static List<string> MultiSzToStringList(char[] multiSz) { var returnValue = new List<string>(); var buildBuffer = new StringBuilder(); for (int i = 0; i <= multiSz.GetUpperBound(0); i++) { if (multiSz[i] != '\0') { buildBuffer.Append(multiSz[i]); } else { if (buildBuffer.Length > 0) { returnValue.Add(buildBuffer.ToString()); buildBuffer.Length = 0; } } } returnValue.Sort(); return returnValue; } public static void CheckStatus(PdhStatus actualStatus, params PdhStatus[] expectedStatus) { for (int i = 0; i <= expectedStatus.GetUpperBound(0); i++) { if (actualStatus == expectedStatus[i]) { return; } } throw new Exception(actualStatus.ToString()); } public static List<string> GetMachineList(string logFileName) { List<string> machines; uint objectBufferLength = 0; PdhStatus pdhStatus = PdhNativeMethods.PdhEnumMachines( logFileName, null, ref objectBufferLength); CheckStatus(pdhStatus, PdhStatus.PDH_MORE_DATA); var objectListBuffer = new char[objectBufferLength]; pdhStatus = PdhNativeMethods.PdhEnumMachines( logFileName, objectListBuffer, ref objectBufferLength); CheckStatus(pdhStatus, PdhStatus.PDH_CSTATUS_VALID_DATA); machines = MultiSzToStringList(objectListBuffer); return machines; } public static List<string> GetObjectList(string logFilename, string machineName) { uint objectBufferLength = 0; PdhStatus pdhStatus = PdhNativeMethods.PdhEnumObjects( logFilename, machineName, null, ref objectBufferLength, PdhDetailLevel.PERF_DETAIL_WIZARD, 0); CheckStatus(pdhStatus, PdhStatus.PDH_MORE_DATA, PdhStatus.PDH_CSTATUS_VALID_DATA); if (pdhStatus == PdhStatus.PDH_MORE_DATA) { var objectListBuffer = new char[objectBufferLength]; pdhStatus = PdhNativeMethods.PdhEnumObjects( logFilename, machineName, objectListBuffer, ref objectBufferLength, PdhDetailLevel.PERF_DETAIL_WIZARD, 0); CheckStatus(pdhStatus, PdhStatus.PDH_CSTATUS_VALID_DATA); return MultiSzToStringList(objectListBuffer); } return new List<string>(); } public static void GetCounterAndInstanceList( string logFilename, string machineName, string objectName, out List<string> counterList, out List<string> instanceList) { uint counterBufferLength = 0; uint instanceBufferLength = 0; PdhStatus pdhStatus = PdhNativeMethods.PdhEnumObjectItems( logFilename, machineName, objectName, null, ref counterBufferLength, null, ref instanceBufferLength, PdhDetailLevel.PERF_DETAIL_WIZARD, 0); CheckStatus(pdhStatus, PdhStatus.PDH_CSTATUS_NO_OBJECT, PdhStatus.PDH_MORE_DATA, PdhStatus.PDH_CSTATUS_VALID_DATA); if (pdhStatus == PdhStatus.PDH_MORE_DATA) { var counterListBuffer = new char[counterBufferLength]; var instanceListBuffer = new char[instanceBufferLength]; pdhStatus = PdhNativeMethods.PdhEnumObjectItems( logFilename, machineName, objectName, counterListBuffer, ref counterBufferLength, instanceListBuffer, ref instanceBufferLength, PdhDetailLevel.PERF_DETAIL_WIZARD, 0); CheckStatus(pdhStatus, PdhStatus.PDH_CSTATUS_VALID_DATA); counterList = MultiSzToStringList(counterListBuffer); instanceList = MultiSzToStringList(instanceListBuffer); } else { counterList = new List<string>(); instanceList = new List<string>(); } } public static SortedList<string, SortedSet<string>> Parse(string dataSource) { var allCounters = new SortedList<string, SortedSet<string>>(); List<string> machines = GetMachineList(dataSource); foreach (string machine in machines) { List<string> counterSets = GetObjectList(dataSource, machine); foreach (string counterSet in counterSets) { SortedSet<string> countersSoFar; if (!allCounters.TryGetValue(counterSet, out countersSoFar)) { countersSoFar = new SortedSet<string>(); allCounters.Add(counterSet, countersSoFar); } List<string> counters; List<string> instances; GetCounterAndInstanceList(dataSource, machine, counterSet, out counters, out instances); foreach (string c in counters) { if (!countersSoFar.Contains(c)) countersSoFar.Add(c); } } } return allCounters; } public static string[] GetCounterPaths(string dataSource) { var counterPaths = new List<string>(); List<string> machines = GetMachineList(dataSource); foreach (string machine in machines) { List<string> counterSets = GetObjectList(dataSource, machine); foreach (string counterSet in counterSets) { List<string> counters; List<string> instances; GetCounterAndInstanceList(dataSource, machine, counterSet, out counters, out instances); foreach (string c in counters) { if (instances.Count == 0) { var sb = new StringBuilder(); sb.Append(machine); sb.Append('\\'); sb.Append(counterSet); sb.Append('\\'); sb.Append(c); counterPaths.Add(sb.ToString()); } else { foreach (string instance in instances) { var sb = new StringBuilder(); sb.Append(machine); sb.Append('\\'); sb.Append(counterSet); sb.Append('('); sb.Append(instance); sb.Append(')'); sb.Append('\\'); sb.Append(c); counterPaths.Add(sb.ToString()); } } } } } return counterPaths.ToArray(); } } }