程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> .NET實例教程 >> Windows Performance Info

Windows Performance Info

編輯:.NET實例教程

下面介紹如何遠程取得  Windows Performance Info

一.性能計數器簡介

系統性能計數器?也許好多朋友沒有用過吧!(獻丑了)此物可謂功能強大,顧名思義就是可以統計 Windows 系統各項性能指標的東西。在 Windows 2000 及以上系統中,如果是默認安裝就會自帶性能計數器程序,大家可以在 “控制面板 -〉管理 -〉性能”中看到該程序。

Windows 系統性能計數器可以實時跟蹤上百項系統性能指標,在該系統程序的繪圖界面上鼠標右擊,選擇“添加計數器”就有可能看到所有可統計的項目。常常在論壇裡看到 一些新朋友問如何自己實現 任務管理器 ,及如何實時獲得每個進程的CPU使用率,內存使用...等等,那麼我想使用系統性能計數器應該是最佳選擇。言歸正傳,實現方法,請看下文。

二.具體實現:

相關API簡介及事例代碼:

1.PdhOpenQuery:打開計數器

PDH_STATUS pdhStatus;
HQUERY phQuery = NULL;
HCOUNTER pCounterHandle = NULL;
pdhStatus = PdhOpenQuery(0, 0, &phQuery);
if (pdhStatus != ERROR_SUCCESS) return false;
// 分配計數器句柄空間
pCounterHandle = (HCOUNTER *)GlobalAlloc(GPTR, sizeof(HCOUNTER));
if (pCounterHandle == NULL) return false;

2.PdhCloseQuery:關閉計數器
pdhStatus = PdhCloseQuery(phQuery);
if (pdhStatus != ERROR_SUCCESS) return false;

3.PdhEnumObjects:枚舉計數項目,該函數有6個參數(詳細請看MSDN)
原型:
PDH_STATUS PdhEnumObjects(
        LPCTSTR szDataSource,    // 必須為 NULL
        LPCTSTR szMachineName,   // 機器名,如果為本機可以為NULL
        LPTSTR mszObjectList,    // 接收全部可用計數項目的緩沖區
        LPDWord pcchBufferLength,  // 緩沖去大小(如果為 0,則該值返回所需大小)
        DWord dwDetailLevel,    // 獲取信息的級別
        BOOL bRefresh        // 一般設置為 TRUE
        );
舉例:
LPTSTR lpsObjectListBuffer = NULL;
LPTSTR lpsthisObject = NULL;
DWord dwObjectListSize = 0;
// 第一步先把緩沖去大小置為0,這樣可獲得所需緩沖區大小
pdhStatus = PdhEnumObjects (

       NULL,
       lpcsMachineName,
       lpsObjectListBuffer,
       &dwObjectListSize,
       PERF_DETAIL_WIZARD,
       TRUE);
if (pdhStatus != ERROR_SUCCESS || pdhStatus != PDH_MORE_DATA) return false;
// 得到緩沖區大小後,分配緩存區內存
lpsObjectListBuffer = (LPTSTR)malloc(dwObjectListSize + 1);
if (lpsObjectListBuffer == NULL) return false;
// 第二步在此調用枚舉函數真正開始枚舉計數項目
pdhStatus = PdhEnumObjects (

       NULL,
       lpcsMachineName,
       lpsObjectListBuffer,
       &dwObjectListSize,
       PERF_DETAIL_WIZARD,
       TRUE);
if (pdhStatus != ERROR_SUCCESS) return false;
// 保存緩沖區地址
lpsthisObject = lpsObjectListBuffer;
// 打印所有可用計數項目
for ( ; *lpsthisObject != 0 ; lpsthisObject += (lstrlen(lpsthisObject) + 1))
{
 printf(lpsthisObject);
}
if (lpsObjectListBuffer)
{
 free (lpsObjectListBuffer);
 lpsObjectListBuffer = NULL ;
 dwObjectListSize = 0;
}

4.PdhEnumObjectItems:枚舉計數器及實例
原型:
PDH_STATUS PdhEnumObjectItems(

         LPCTSTR szDataSource,        // 必須為NULL
         LPCTSTR szMachineName,       // 機器名,如果為本機可以為NULL
         LPCTSTR szObjectName,        // 計數項目(通過PdhEnumObjects函數可獲得所有可用項目)
         LPTSTR mszCounterList,       // 計數器緩沖區
         LPDWord pcchCounterListLength,   // 計數器緩沖區大小
         LPTSTR mszInstanceList,       // 計數實例緩沖區
         LPDWord pcchInstanceListLength,   // 計數實例緩沖區大小
         DWord dwDetailLevel,        // 獲取信息的級別
         DWord dwFlags            // 一般設置為 TRUE
         );
舉例:該函數的方法同上一函數(PdhEnumObjects),具體請看MSDN或本文附帶的測試工程代碼

5.PdhAddCounter:添加計數器
統計感興趣的系統信息時,必須先將對應的計數器添加進來
原型:
PDH_STATUS PdhAddCounter(
       PDH_HQUERY hQuery,     // 為PdhOpenQuery打開的句柄
       LPCTSTR szFullCounterPath, // 計數器路徑(最大長度為 PDH_MAX_COUNTER_PATH)
       DWord_PTR dwUserData,    // 置為 0
       PDH_HCOUNTER* phCounter   // 計數器句柄空間(本文中在PdhOpenQuery函數後已分配)
       );
舉例:
// 已獲取winlogon.exe進程的CPU使用率為例
// 通過枚舉並查看計數項目說明可以知道 process 項目是和進程有關的項目
// 再通過枚舉計數器和事例並查看說明可以知道 process 項目下的% Processor Time計數器是關於進程CPU使率的
// 最後在計數器事例中看到winlogon進程(表明該進程正在運行)
pdhStatus = PdhAddCounter (phQuery, "\\process(winlogon)\\% Processor Time", 0, pCounterHandle);
if (pdhStatus != ERROR_SUCCESS) return false;
提示:有些計數器沒有實例,比如:要得到系統自啟動到現在所運行的秒數,那麼該計數項目為System,計數器為System Up Time,計數器實例為NULL,這時的計數器路徑為"\System\System Up Time"

6.PdhCollectQueryData: 准備獲取當前數據
舉例:
pdhStatus = PdhCollectQueryData(phQuery);
if (pdhStatus != ERROR_SUCCESS)return false;

7.PdhGetFormattedCounterValue:得到數據
舉例:
pdhStatus = PdhGetFormattedCounterValue (pCounterHandle, PDH_FMT_DOUBLE,
           &dwctrType, &fmtValue);
if (pdhStatus != ERROR_SUCCESS) return false;
// PDH_FMT_DOUBLE表示返回double型數據,當然還可以返回int等類型數據,請查MSDN
// 獲取下一時刻數據
pdhStatus = PdhCollectQueryData(phQuery);
if (pdhStatus != ERROR_SUCCESS)return false;
提示:pCounterHandle為PdhAddCounter得到的句柄,可以不同的pCounterHandle獲得不同計數值

8.PdhRemoveCounter:移出計數器
不想獲取某項計數值時,應該移出該計數器,已節省資源
舉例:
if (PdhRemoveCounter(pdhCouner) != ERROR_SUCCESS) return false;
該函數參數為計數器句柄

至此,如果使用計數器實時跟蹤系統信息已經講解完畢。如還有不明白的朋友請詳細察看MSDN或與

.最後實例獻上

void Main::main()
{
    // http://www7a.biglobe.ne.jp/~lshen/EternalWindows/WinDevelop/PDH/PDH05.Html
    // http://nienIE.com/~masapico/api_PdhGetCounterInfo.Html
    // http://nienIE.com/~masapico/api_PdhExpandCounterPath.Html

//建立遠程IPC鏈接(你要對方的administrator權獻的用戶)
    NETRESOURCE   nr; 
    nr.dwType   =   RESOURCETYPE_ANY; 
    nr.lpLocalName   =   NULL; 
    nr.lpRemoteName   =  "\\\\PC211";
    nr.lpProvider   =   NULL; 
    nr.dwDisplayType = RESOURCEDISPLAYTYPE_DOMAIN;    //RESOURCEDISPLAYTYPE_GENERIC;//
    nr.dwScope = RESOURCE_CONNECTED;
    nr.lpComment = NULL;
   
    DWord dwRet = WNetAddConnection2(&nr,"pc211","pc211",0);
    if(ERROR_SUCCESS != dwRet){
        printf("WNetAddConnection2 failure : %d \n",dwRet);
        return;
    }

    HQUERY hQuery;
    HCOUNTER hCounter[10];
    PDH_FMT_COUNTERVALUE FmtValue;

    PdhOpenQuery(NULL, 0, &hQuery);
    PdhAddCounter(hQuery, "\\\\PC211\\Processor(_Total)\\% Processor Time", 0, &hCounter[0]);
    PdhAddCounter(hQuery, "\\Memory\\Available Bytes", 0, &hCounter[1]);
    PdhCollectQueryData(hQuery);

    for(int i=0; i<10; i++) {
        Sleep(1000);
        PdhCollectQueryData(hQuery);
        PdhGetFormattedCounterValue(hCounter[0], PDH_FMT_DOUBLE, NULL, &FmtValue);
   ;  printf("CPU使用率: %f%%\t", FmtValue.doubleValue);
        PdhGetFormattedCounterValue(hCounter[1], PDH_FMT_LONG|PDH_FMT_NOSCALE, NULL, &FmtValue);
        printf("MEM使用率: %d\n", FmtValue.longValue);
    }

    PdhCloseQuery(hQuery);
}


全部介紹完畢,希望本文能對大家有所幫助,祝大家愉快。

不明請來電詢問.QQ:9309696   Email:[email protected]

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved