PDH:获取系统计数器路径的方法

performance data helper库函数可以说是非常强大
如何获取计数器的路径呢,msdn讲述的规则可以说是非常的麻烦
当然,msdn也告诉我们可以使用 PdhBrowseCounters 函数来选择计数器,其实系统本身也有现成的程序给我们提供计数器路径

首先运行perfmon.msc
PDH:获取系统计数器路径的方法_第1张图片
打开之后是这样的
PDH:获取系统计数器路径的方法_第2张图片
然后在如图所示菜单弹出的地方右键
PDH:获取系统计数器路径的方法_第3张图片
点击”添加计数器”
PDH:获取系统计数器路径的方法_第4张图片
弹出一个对话框
PDH:获取系统计数器路径的方法_第5张图片
这是我自己创建的一个叫做”jeff”的作业对象
PDH:获取系统计数器路径的方法_第6张图片
点击添加,列表框中出现了一个计数器对象
PDH:获取系统计数器路径的方法_第7张图片
但是必须要有全路径,当然是可以获取的
在列表框中右击
PDH:获取系统计数器路径的方法_第8张图片
点击”属性”
PDH:获取系统计数器路径的方法_第9张图片
高亮显示的地方就是作业对象的计数器的路径了
现发上测试代码:

#define _WIN32_WINNT 0x0500
#include 
#include 
#include 
#pragma comment(lib,"Kernel32.lib")
#pragma comment(lib,"pdh.lib")
using namespace std;
void SetJobObject(HANDLE hObj);
void ShowJobInformation(HANDLE hObj);
bool QueryJobCountersByPDH(TCHAR* JobName,TCHAR* JobCountPath);
int main()
{
    int err;
    bool suc;
    HANDLE hObj=CreateJobObject(NULL,TEXT("jeff"));
    if(NULL==hObj)
    {
        cout<<"创建作业对象失败"<return 1;
    }
    SetJobObject(hObj);
    STARTUPINFO si={sizeof(si)};
    PROCESS_INFORMATION pi_spy={0};
    PROCESS_INFORMATION pi_notepad={0};
    TCHAR szPath[MAX_PATH]=TEXT("D:/vs2005/Common7/Tools/spyxx.exe");
    TCHAR Notepath[MAX_PATH]=TEXT("notepad");
    CreateProcess(NULL,szPath,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&si,&pi_spy);
    CreateProcess(NULL,Notepath,NULL,NULL,false,CREATE_SUSPENDED,NULL,NULL,&si,&pi_notepad);
    AssignProcessToJobObject(hObj,pi_notepad.hProcess);
    SetJobObject(hObj);
    AssignProcessToJobObject(hObj,pi_spy.hProcess);
    ResumeThread(pi_spy.hThread);
    ResumeThread(pi_notepad.hThread);
    CloseHandle(pi_spy.hThread);
    CloseHandle(pi_notepad.hThread);
    HANDLE h[3];
    h[0]=pi_spy.hProcess;
    h[1]=pi_notepad.hProcess;
    h[2]=hObj;
    //ShowPDHDialog();
    TCHAR CounterPath[MAX_PATH]=TEXT("\\Job Object(jeff)\\Current % Processor Time");
    suc=QueryJobCountersByPDH(TEXT("jeff"),CounterPath);
    if(!suc)
    {
        cout<<"获取jeff作业信息失败"<return 2;
    }
    DWORD dw=WaitForMultipleObjects(3,h,false,INFINITE);
    switch(dw-WAIT_OBJECT_0)
    {
    case 0:
        cout<<"spy结束"<break;
    case 1:
        cout<<"notepad结束"<break;
    case 2:
        cout<<"作业结束"<break;
    }
    ShowJobInformation(hObj);
    CloseHandle(pi_spy.hProcess);
    CloseHandle(pi_notepad.hProcess);
    CloseHandle(hObj);
    system("pause");
    return 0;
}

void SetJobObject(HANDLE hObj)
{
    if(hObj==NULL)
    {
        cout<<"传入的作业句柄为空"<return;
    }
    JOBOBJECT_BASIC_LIMIT_INFORMATION job1={0};
    job1.PerJobUserTimeLimit.QuadPart=10000000;
    job1.PriorityClass=IDLE_PRIORITY_CLASS;
    job1.MinimumWorkingSetSize=1;
    job1.MaximumWorkingSetSize=10;
    job1.ActiveProcessLimit=5;
    job1.LimitFlags=JOB_OBJECT_LIMIT_PRIORITY_CLASS|JOB_OBJECT_LIMIT_JOB_TIME|JOB_OBJECT_LIMIT_WORKINGSET|JOB_OBJECT_LIMIT_ACTIVE_PROCESS;
    bool suc=SetInformationJobObject(hObj,JobObjectBasicLimitInformation,&job1,sizeof(job1));
    if(suc)
    {
        cout<<"设置成功"<0};
    job2.UIRestrictionsClass=JOB_OBJECT_UILIMIT_EXITWINDOWS|JOB_OBJECT_UILIMIT_HANDLES;
    suc=SetInformationJobObject(hObj,JobObjectBasicUIRestrictions,&job2,sizeof(JOBOBJECT_BASIC_UI_RESTRICTIONS));
    if(suc)
    {
        cout<<"设置成功"<void ShowJobInformation(HANDLE hObj)
{
    if(hObj==NULL)
    {
        cout<<"传入的作业句柄为空"<return;
    }
    JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION job={0};
    DWORD length;
    bool ret=QueryInformationJobObject(hObj,JobObjectBasicAndIoAccountingInformation,&job,sizeof(job),&length);
    if(!ret)
    {
        cout<<"获取作业信息失败"<return;
    }
    cout<<"job.BasicInfo.TotalUserTime:"<cout<<"job.BasicInfo.TotalKernelTime:"<cout<<"job.BasicInfo.ThisPeriodTotalUserTime:"<cout<<"job.BasicInfo.ThisPeriodTotalKernelTime:"<cout<<"job.BasicInfo.TotalPageFaultCount:"<cout<<"job.BasicInfo.TotalTerminatedProcesses:"<cout<<"job.BasicInfo.ActiveProcesses:"<cout<<"job.BasicInfo.TotalProcesses:"<cout<<"job.IoInfo.OtherOperationCount:"<cout<<"job.IoInfo.OtherTransferCount:"<cout<<"job.IoInfo.ReadOperationCount:"<cout<<"job.IoInfo.ReadTransferCount:"<cout<<"job.IoInfo.WriteOperationCount:"<cout<<"job.IoInfo.WriteTransferCount:"<bool QueryJobCountersByPDH(TCHAR* JobName,TCHAR* JobCountPath)
{
    PDH_HQUERY hQuery;
    PDH_STATUS status;
    //创建一个查询对象
    status=PdhOpenQuery(NULL,NULL,&hQuery);
    if(ERROR_SUCCESS!=status)
    {
        return false;
    }
    //添加计数器(句柄其实是个指针)
    HCOUNTER counter;
    counter=(HCOUNTER*)GlobalAlloc(GPTR,sizeof(HCOUNTER));
    status=PdhAddCounter(hQuery,JobCountPath,NULL,&counter);
    if(ERROR_SUCCESS!=status)
    {
        return false;
    }
    //收集性能数据
    status=PdhCollectQueryData(hQuery);
    if(ERROR_SUCCESS!=status)
    {
        return false;
    }
    Sleep(1000);
    status=PdhCollectQueryData(hQuery);
    if(ERROR_SUCCESS!=status)
    {
        return false;
    }
    Sleep(1000);
    status=PdhCollectQueryData(hQuery);
    if(ERROR_SUCCESS!=status)
    {
        return false;
    }
    //显示性能数据
    DWORD countertype;
    PDH_FMT_COUNTERVALUE countervalue;
    status=PdhGetFormattedCounterValue(counter,PDH_FMT_LARGE,&countertype,&countervalue);
    if(ERROR_SUCCESS!=status)
    {
        return false;
    }
    cout<//关闭查询
    PdhCloseQuery(hQuery);
    return true;
}

实测计数器路径有本机名的情况下,程序会发生无法预测的问题,去掉主机名程序顺利完成
“\Job Object(jeff)\Current % Processor Time”去掉前面的主机名
测试结果
PDH:获取系统计数器路径的方法_第10张图片

你可能感兴趣的:(PDH:获取系统计数器路径的方法)