效能監控器以即時或查看曆史資料的方式顯示了內建的 Windows 效能計數器。可以通過拖放或建立自訂資料收集器集合工具將效能計數器添加到效能監控器。其特徵在於可以直觀地查看效能日誌資料的多個圖表視圖。可以在效能監控器中建立自訂視圖,該視圖可以匯出為資料收集器集合工具以便與效能和日誌記錄功能一起使用。
本文介紹通過API,讀取效能監控器中的資料。
一、API介紹:
1、PdhOpenQuery:擷取效能監控器資料查詢控制代碼;
2、PdhAddCounter:添加計數器;
3、PdhCollectQueryData:查詢效能監控器資料;
4、PdhGetFormattedCounterValue:擷取指定計數器數值;
二、執行個體代碼:
1、pdh標頭檔,在SDK中:
#include <Pdh.h>
2、匯入lib:
pdh.lib
3、代碼:
void CTestDlg::TestPDH()
{
CString strInfo = "系統效能:\r\n";
CString strTemp = "";
HQUERY hQuery;
HCOUNTER hcCommitTotal, hcCommitLimit;
HCOUNTER hcKernelPaged, hcKernelNonpaged;
HCOUNTER hcSysHandleCount, hcProcesses, hcThreads;
PDH_STATUS lStatus = PdhOpenQuery(NULL, NULL, &hQuery);
if (lStatus != ERROR_SUCCESS)
{
return;
}
PdhAddCounter(hQuery, _T("\\Memory\\Committed Bytes"), NULL, &hcCommitTotal);
PdhAddCounter(hQuery, _T("\\Memory\\Commit Limit"), NULL, &hcCommitLimit);
PdhAddCounter(hQuery, _T("\\Memory\\Pool Paged Bytes"), NULL, &hcKernelPaged);
PdhAddCounter(hQuery, _T("\\Memory\\Pool Nonpaged Bytes"), NULL, &hcKernelNonpaged);
PdhAddCounter(hQuery, _T("\\Process(_Total)\\Handle Count"), NULL, &hcSysHandleCount);
PdhAddCounter(hQuery, _T("\\System\\Processes"), NULL, &hcProcesses);
PdhAddCounter(hQuery, _T("\\System\\Threads"), NULL, &hcThreads);
HCOUNTER hcCPU = NULL;
HCOUNTER hcThreadCount = NULL;
HCOUNTER hcHandleCount = NULL;
HCOUNTER hcWorkingSet = NULL;
HCOUNTER hcWorkingSetPeak = NULL;
HCOUNTER hcPageFileBytes = NULL;
PDH_COUNTER_PATH_ELEMENTS elements;
char szBuf[1024] = "";
DWORD dwBufSize = 0;
char szInstanceName[256] = "360se";
elements.szMachineName = NULL;
elements.szObjectName = "Process";
elements.szInstanceName = szInstanceName;
elements.szParentInstance = NULL;
elements.dwInstanceIndex = -1;
elements.szCounterName = const_cast<char *>("% Processor Time");
dwBufSize = sizeof(szBuf);
PdhMakeCounterPath(&elements, szBuf, &dwBufSize, 0);
lStatus = PdhAddCounter(hQuery, szBuf, NULL, &hcCPU);
if (lStatus != ERROR_SUCCESS)
{
return;
}
elements.szCounterName = const_cast<char *>("Thread Count");
dwBufSize = sizeof(szBuf);
PdhMakeCounterPath(&elements, szBuf, &dwBufSize, 0);
lStatus = PdhAddCounter(hQuery, szBuf, NULL, &hcThreadCount);
if (lStatus != ERROR_SUCCESS)
{
return;
}
elements.szCounterName = const_cast<char *>("Handle Count");
dwBufSize = sizeof(szBuf);
PdhMakeCounterPath(&elements, szBuf, &dwBufSize, 0);
lStatus = PdhAddCounter(hQuery, szBuf, NULL, &hcHandleCount);
if (lStatus != ERROR_SUCCESS)
{
return;
}
elements.szCounterName = const_cast<char *>("Working set");
dwBufSize = sizeof(szBuf);
PdhMakeCounterPath(&elements, szBuf, &dwBufSize, 0);
lStatus = PdhAddCounter(hQuery, szBuf, NULL, &hcWorkingSet);
if (lStatus != ERROR_SUCCESS)
{
return;
}
elements.szCounterName = const_cast<char *>("Working set Peak");
dwBufSize = sizeof(szBuf);
PdhMakeCounterPath(&elements, szBuf, &dwBufSize, 0);
lStatus = PdhAddCounter(hQuery, szBuf, NULL, &hcWorkingSetPeak);
if (lStatus != ERROR_SUCCESS)
{
return;
}
elements.szCounterName = const_cast<char *>("Page File Bytes");
dwBufSize = sizeof(szBuf);
PdhMakeCounterPath(&elements, szBuf, &dwBufSize, 0);
lStatus = PdhAddCounter(hQuery, szBuf, NULL, &hcPageFileBytes);
if (lStatus != ERROR_SUCCESS)
{
return;
}
PDH_FMT_COUNTERVALUE cv;
lStatus = PdhCollectQueryData(hQuery);
if (lStatus != ERROR_SUCCESS)
{
return;
}
// CPU時間,必須等待一下
Sleep(100);
lStatus = PdhCollectQueryData(hQuery);
if (lStatus != ERROR_SUCCESS)
{
return;
}
// 控制代碼總數
lStatus = PdhGetFormattedCounterValue(hcSysHandleCount, PDH_FMT_LONG, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("控制代碼總數 : %u\r\n", cv.longValue);
strInfo += strTemp;
}
// 線程總數
lStatus = PdhGetFormattedCounterValue(hcThreads, PDH_FMT_LONG, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("線程總數 : %u\r\n", cv.longValue);
strInfo += strTemp;
}
// 進程總數
lStatus = PdhGetFormattedCounterValue(hcProcesses, PDH_FMT_LONG, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("進程總數 : %u\r\n", cv.longValue);
strInfo += strTemp;
}
// 核心記憶體:分頁數
lStatus = PdhGetFormattedCounterValue(hcKernelPaged, PDH_FMT_LARGE, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("核心記憶體:分頁數 : %u\r\n", cv.largeValue / 1024);
strInfo += strTemp;
}
// 核心記憶體:未分頁數
lStatus = PdhGetFormattedCounterValue(hcKernelNonpaged, PDH_FMT_LARGE, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("核心記憶體:未分頁數 : %u\r\n", cv.largeValue / 1024);
strInfo += strTemp;
}
// 認可用量:總數
lStatus = PdhGetFormattedCounterValue(hcCommitTotal, PDH_FMT_LARGE, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("認可用量:總數 : %u\r\n", cv.largeValue / 1024);
strInfo += strTemp;
}
// 認可用量:限制
lStatus = PdhGetFormattedCounterValue(hcCommitLimit, PDH_FMT_LARGE, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("認可用量:限制 : %u\r\n", cv.largeValue / 1024);
strInfo += strTemp;
}
// 以下360rp進程資訊
strInfo += "\r\n";
strInfo += szInstanceName;
strInfo += "進程:\r\n";
// CPU時間,注意必須加上PDH_FMT_NOCAP100參數,否則多核CPU會有問題,詳見MSDN
lStatus = PdhGetFormattedCounterValue(hcCPU, PDH_FMT_DOUBLE | PDH_FMT_NOCAP100, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("CPU : %f\r\n", cv.doubleValue / 2);
strInfo += strTemp;
}
// 線程數
lStatus = PdhGetFormattedCounterValue(hcThreadCount, PDH_FMT_LONG, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("線程數 : %u\r\n", cv.longValue);
strInfo += strTemp;
}
// 控制代碼數
lStatus = PdhGetFormattedCounterValue(hcHandleCount, PDH_FMT_LONG, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("控制代碼數 : %u\r\n", cv.longValue);
strInfo += strTemp;
}
// 記憶體使用量
lStatus = PdhGetFormattedCounterValue(hcWorkingSet, PDH_FMT_LARGE, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("記憶體使用量 : %u\r\n", static_cast<LONG>(cv.largeValue / 1024));
strInfo += strTemp;
}
// 高峰記憶體使用量
lStatus = PdhGetFormattedCounterValue(hcWorkingSetPeak, PDH_FMT_LARGE, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("高峰記憶體使用量 : %u\r\n", static_cast<LONG>(cv.largeValue / 1024));
strInfo += strTemp;
}
// 虛擬記憶體大小
lStatus = PdhGetFormattedCounterValue(hcPageFileBytes, PDH_FMT_LARGE, NULL, &cv);
if (lStatus == ERROR_SUCCESS)
{
strTemp.Format("虛擬記憶體大小 : %u\r\n", static_cast<LONG>(cv.largeValue / 1024));
strInfo += strTemp;
}
m_staticInfo.SetWindowText(strInfo);
PdhRemoveCounter(hcCommitTotal);
PdhRemoveCounter(hcCommitLimit);
PdhRemoveCounter(hcKernelPaged);
PdhRemoveCounter(hcKernelNonpaged);
PdhRemoveCounter(hcSysHandleCount);
PdhRemoveCounter(hcProcesses);
PdhRemoveCounter(hcThreads);
PdhRemoveCounter(hcCPU);
PdhRemoveCounter(hcThreadCount);
PdhRemoveCounter(hcHandleCount);
PdhRemoveCounter(hcWorkingSet);
PdhRemoveCounter(hcWorkingSetPeak);
PdhRemoveCounter(hcPageFileBytes);
PdhCloseQuery(hQuery);
}
4、運行結果: