Advertisement
Guest User

InstanceNameUtility

a guest
Nov 17th, 2017
400
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C# 4.61 KB | None | 0 0
  1. using System;
  2. using System.Diagnostics;
  3. using System.Linq;
  4. using System.Runtime.InteropServices;
  5.  
  6. namespace Kontur.Core.Metrics
  7. {
  8.     internal static unsafe class InstanceNameUtility
  9.     {
  10.         public static string ObtainInstanceNameForProcessSlow(int pid, string processName)
  11.         {
  12.             var category = new PerformanceCounterCategory("Process");
  13.  
  14.             foreach (var instance in category.GetInstanceNames().Where(name => name.StartsWith(processName)))
  15.             {
  16.                 using (var counter = new System.Diagnostics.PerformanceCounter("Process", "ID Process", instance, true))
  17.                 {
  18.                     var counterProcessId = (int)counter.RawValue;
  19.                     if (counterProcessId == pid)
  20.                         return instance;
  21.                 }
  22.             }
  23.  
  24.             return processName;
  25.         }
  26.  
  27.         public static string ObtainInstanceNameForProcess(int pid, string processName)
  28.         {
  29.             const uint pdhMoreData = 0x800007d2;
  30.  
  31.             uint result;
  32.  
  33.             IntPtr query;
  34.  
  35.             if ((result = PdhOpenQuery(null, IntPtr.Zero, out query)) != 0)
  36.                 FailWithError(result, "PdhOpenQuery");
  37.  
  38.             try
  39.             {
  40.                 IntPtr counter;
  41.  
  42.                 if ((result = PdhAddCounter(query, @"\Process(" + processName + @"*)\ID Process", IntPtr.Zero, out counter)) != 0)
  43.                     FailWithError(result, "PdhAddCounter");
  44.  
  45.                 if ((result = PdhCollectQueryData(query)) != 0)
  46.                     FailWithError(result, "PdhCollectQueryData");
  47.  
  48.                 while (true)
  49.                 {
  50.                     int bufferSize = 0;
  51.                     int itemCount;
  52.  
  53.                     if ((result = PdhGetRawCounterArray(counter, ref bufferSize, out itemCount, null)) != pdhMoreData)
  54.                         FailWithError(result, "PdhGetRawCounterArray");
  55.  
  56.                     var buffer = new byte[bufferSize];
  57.  
  58.                     fixed (byte* ptr = buffer)
  59.                     {
  60.                         result = PdhGetRawCounterArray(counter, ref bufferSize, out itemCount, ptr);
  61.  
  62.                         if (result == pdhMoreData)
  63.                             continue;
  64.  
  65.                         if (result != 0)
  66.                             FailWithError(result, "PdhGetRawCounterArray");
  67.  
  68.                         var instanceIndex = 0;
  69.  
  70.                         for (int i = 0; i < itemCount; i++)
  71.                         {
  72.                             var currentPid = ((PdhRawCounterItem*)ptr)[i].RawValue.FirstValue;
  73.                             var currentName = new string(((PdhRawCounterItem*)ptr)[i].Name);
  74.  
  75.                             if (currentName != processName)
  76.                                 continue;
  77.  
  78.                             if (currentPid == pid)
  79.                                 return instanceIndex == 0 ? processName : processName + "#" + instanceIndex;
  80.  
  81.                             instanceIndex++;
  82.                         }
  83.                     }
  84.  
  85.                     throw new ArgumentException("Failed to find instance name for PID " + pid);
  86.                 }
  87.             }
  88.             finally
  89.             {
  90.                 PdhCloseQuery(query);
  91.             }
  92.         }
  93.  
  94.         private static void FailWithError(uint error, string function)
  95.         {
  96.             throw new Exception(String.Format("{0} failed with code {1:x8}", function, error));
  97.         }
  98.  
  99.         [DllImport("pdh.dll")]
  100.         private static extern uint PdhOpenQuery(string dataSource, IntPtr userData, out IntPtr query);
  101.  
  102.         [DllImport("pdh.dll")]
  103.         private static extern uint PdhCloseQuery(IntPtr query);
  104.  
  105.         [DllImport("pdh.dll")]
  106.         private static extern uint PdhAddCounter(IntPtr query, string path, IntPtr userData, out IntPtr counter);
  107.  
  108.         [DllImport("pdh.dll")]
  109.         private static extern uint PdhCollectQueryData(IntPtr query);
  110.  
  111.         [DllImport("pdh.dll")]
  112.         private static extern uint PdhGetRawCounterArray(IntPtr counter, ref int bufferSize, out int itemCount, byte* buffer);
  113.  
  114.         [StructLayout(LayoutKind.Sequential)]
  115.         private struct PdhRawCounterItem
  116.         {
  117.             public readonly sbyte* Name;
  118.             public readonly PdhRawCounter RawValue;
  119.         }
  120.  
  121.         [StructLayout(LayoutKind.Sequential)]
  122.         private struct PdhRawCounter
  123.         {
  124.             public readonly int CStatus;
  125.             public readonly long TimeStamp;
  126.             public readonly long FirstValue;
  127.             public readonly long SecondValue;
  128.             public readonly int MultiCount;
  129.         }
  130.     }
  131. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement