やりたいこと
C#でパフォーマンスデータを読み取りたい。。
C#では.Netフレームワークが提供するカウンタークラスは
ライブカウンター値の読み取りと書き込みには役立ちますが、
パフォーマンスログにバインドすることができないようです。。
なので、PDH APIを使用しパフォーマンスログへのバインドを実現させます。
定義
PDH_FMT_COUNTERVALUE structure (pdh.h)
[StructLayout(LayoutKind.Explicit)]
public struct PDH_FMT_COUNTERVALUE
{
[FieldOffset(0)]
public UInt32 CStatus;
[FieldOffset(1)]
public int longValue;
[FieldOffset(1)]
public double doubleValue;
[FieldOffset(1)]
public long longLongValue;
[FieldOffset(1)]
public IntPtr AnsiStringValue;
[FieldOffset(1)]
public IntPtr WideStringValue;
}
PdhOpenQueryA function (pdh.h)
[DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern UInt32 PdhOpenQuery( string szDataSource, IntPtr dwUserData,out PdhQueryHandle phQuery);
PdhOpenQueryH function (pdh.h)
[DllImport("pdh.dll", SetLastError = true)]
public static extern UInt32 PdhOpenQueryH(PdhLogHandle hDataSource,IntPtr dwUserData,out PdhQueryHandle phQuery);
PdhBindInputDataSourceA function (pdh.h)
[DllImport("pdh.dll", SetLastError = true)]
public static extern UInt32 PdhBindInputDataSource(out PdhLogHandle phDataSource,string szLogFileNameList);
PdhCloseLog function (pdh.h)
[DllImport("pdh.dll", SetLastError = true)]
public static extern UInt32 PdhCloseLog(IntPtr hLog,long dwFlags);
PdhCloseQuery function (pdh.h)
[DllImport("pdh.dll", SetLastError = true)]
public static extern UInt32 PdhCloseQuery(IntPtr hQuery);
PdhRemoveCounter function (pdh.h)
[DllImport("pdh.dll", SetLastError = true)]
public static extern UInt32 PdhRemoveCounter(IntPtr hQuery);
PdhAddCounterA function (pdh.h)
[DllImport("pdh.dll", SetLastError = true, CharSet = CharSet.Auto)]
public static extern UInt32 PdhAddCounter(
PdhQueryHandle hQuery,
string szFullCounterPath,
IntPtr dwUserData,
out PdhCounterHandle phCounter);
PdhCollectQueryData function (pdh.h)
[DllImport("pdh.dll", SetLastError = true)]
public static extern UInt32 PdhCollectQueryData(PdhQueryHandle phQuery);
PdhCollectQueryData function (pdh.h)
[DllImport("pdh.dll", SetLastError = true)]
public static extern UInt32 PdhGetFormattedCounterValue(
PdhCounterHandle phCounter,
PdhFormat dwFormat,
IntPtr lpdwType,
out PDH_FMT_COUNTERVALUE pValue);
実装
UInt32 result = PdhApi.PdhOpenQuery(null, IntPtr.Zero, out query);
※szDataSource(第一引数)は、NULLでなければならない。。
string counterName = @"\Processor(0)\% Processor Time";
result = PdhApi.PdhAddCounter(query, counterName, IntPtr.Zero, out counter);
.
result = PdhApi.PdhCollectQueryData(query);
PDH_FMT_COUNTERVALUE value;
result = PdhApi.PdhGetFormattedCounterValue(counter, PdhFormat.PDH_FMT_DOUBLE, IntPtr.Zero, out value);
※複数のサンプルを必要とする場合は、CounterValueを使用して取得する。
Acknowledgments
Development Errata
http://adamserrata.blogspot.com/2009/01/how-to-use-c-to-read-performance-data.html
tanner,thank you.