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

来源:互联网 发布:微软人工智能操作系统 编辑:程序博客网 时间:2024/06/05 02:02

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

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

#define _WIN32_WINNT 0x0500#include <windows.h>#include <iostream>#include <Pdh.h>#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<<"创建作业对象失败"<<endl;        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作业信息失败"<<endl;        return 2;    }    DWORD dw=WaitForMultipleObjects(3,h,false,INFINITE);    switch(dw-WAIT_OBJECT_0)    {    case 0:        cout<<"spy结束"<<endl;        break;    case 1:        cout<<"notepad结束"<<endl;        break;    case 2:        cout<<"作业结束"<<endl;        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<<"传入的作业句柄为空"<<endl;        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<<"设置成功"<<endl;    }    JOBOBJECT_BASIC_UI_RESTRICTIONS job2={0};    job2.UIRestrictionsClass=JOB_OBJECT_UILIMIT_EXITWINDOWS|JOB_OBJECT_UILIMIT_HANDLES;    suc=SetInformationJobObject(hObj,JobObjectBasicUIRestrictions,&job2,sizeof(JOBOBJECT_BASIC_UI_RESTRICTIONS));    if(suc)    {        cout<<"设置成功"<<endl;    }}void ShowJobInformation(HANDLE hObj){    if(hObj==NULL)    {        cout<<"传入的作业句柄为空"<<endl;        return;    }    JOBOBJECT_BASIC_AND_IO_ACCOUNTING_INFORMATION job={0};    DWORD length;    bool ret=QueryInformationJobObject(hObj,JobObjectBasicAndIoAccountingInformation,&job,sizeof(job),&length);    if(!ret)    {        cout<<"获取作业信息失败"<<endl;        return;    }    cout<<"job.BasicInfo.TotalUserTime:"<<job.BasicInfo.TotalUserTime.QuadPart<<endl;    cout<<"job.BasicInfo.TotalKernelTime:"<<job.BasicInfo.TotalKernelTime.QuadPart<<endl;    cout<<"job.BasicInfo.ThisPeriodTotalUserTime:"<<job.BasicInfo.ThisPeriodTotalUserTime.QuadPart<<endl;    cout<<"job.BasicInfo.ThisPeriodTotalKernelTime:"<<job.BasicInfo.ThisPeriodTotalKernelTime.QuadPart<<endl;    cout<<"job.BasicInfo.TotalPageFaultCount:"<<job.BasicInfo.TotalPageFaultCount<<endl;    cout<<"job.BasicInfo.TotalTerminatedProcesses:"<<job.BasicInfo.TotalTerminatedProcesses<<endl;    cout<<"job.BasicInfo.ActiveProcesses:"<<job.BasicInfo.ActiveProcesses<<endl;    cout<<"job.BasicInfo.TotalProcesses:"<<job.BasicInfo.TotalProcesses<<endl;    cout<<"job.IoInfo.OtherOperationCount:"<<job.IoInfo.OtherOperationCount<<endl;    cout<<"job.IoInfo.OtherTransferCount:"<<job.IoInfo.OtherTransferCount<<endl;    cout<<"job.IoInfo.ReadOperationCount:"<<job.IoInfo.ReadOperationCount<<endl;    cout<<"job.IoInfo.ReadTransferCount:"<<job.IoInfo.ReadTransferCount<<endl;    cout<<"job.IoInfo.WriteOperationCount:"<<job.IoInfo.WriteOperationCount<<endl;    cout<<"job.IoInfo.WriteTransferCount:"<<job.IoInfo.WriteTransferCount<<endl;}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<<countervalue.largeValue<<endl;    //关闭查询    PdhCloseQuery(hQuery);    return true;}

实测计数器路径有本机名的情况下,程序会发生无法预测的问题,去掉主机名程序顺利完成
“\Job Object(jeff)\Current % Processor Time”去掉前面的主机名
测试结果
这里写图片描述

原创粉丝点击