性能监视器以实时或查看历史数据的方式显示了内置的 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、运行结果截图:
![](http://hi.csdn.net/attachment/201202/29/0_1330509561ZN5h.gif)