windows系統效能計數器函數

來源:互聯網
上載者:User
系統效能計數器[Z]

FROM:http://hi.baidu.com/wlzqi/blog/item/d9782e73f4b4ba1c8701b092.html

上面的地址是專家的地址,有什麼問題請那邊看

一.效能計數器簡介

系統效能計數器?也許好多朋友沒有用過吧!(獻醜了)此物可謂功能強大,顧名思義就是可以統計 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, " 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或與
Email: 或 QQ:8573980聯絡。

.最後再附帶介紹一個相關API PdhGetCounterInfo,這個API與使用計數器並無關係,但是,它可以讓你明白你所感興趣的計數器的路徑。既它可以得到每個計數器的項目的描述資訊(可是中文的哦!)
舉例:
以擷取系統自啟動到現在所啟動並執行秒數為例
PDH_COUNTER_INFO pdhCounterInfo;
DWORD dwCounterBuffsize;
// 添加計數器
pdhStatus = PdhAddCounter(phQuery, " Up Time", 0, pCounterHandle);
if (pdhStatus != ERROR_SUCCESS) return false;
// 得到緩衝區大小
pdhStatus = PdhGetCounterInfo(*pCounterHandle, TRUE, &dwCounterBuffsize, NULL);
if (pdhStatus != ERROR_SUCCESS || pdhStatus != PDH_MORE_DATA) return false;
// 設定緩衝區
BYTE * byCounterBuff = (BYTE *)malloc(dwCounterBuffsize);
// 擷取資訊
pdhStatus = PdhGetCounterInfo (*pCounterHandle, TRUE, &dwCounterBuffsize, (PPDH_COUNTER_INFO)byCounterBuff);
if (pdhStatus != ERROR_SUCCESS) return false;
pdhCounterInfo = * (PPDH_COUNTER_INFO)byCounterBuff;
// 列印得到的資訊
printf(pdhCounterInfo->szExplainText);

以上列印得資訊類似:"System Up Time 指電腦自上次啟動後已經啟動並執行時間(用秒計算)。這個計數值顯示啟動時間和目前時間之差。"

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

在別處找到的一個PDH的一些關鍵定義

#define PDH_CSTATUS_VALID_DATA   0x0
#define PDH_CSTATUS_NEW_DATA   0x1
#define PDH_CSTATUS_NO_MACHINE   0x800007D0
#define PDH_CSTATUS_NO_INSTANCE   0x800007D1
#define PDH_MORE_DATA   0x800007D2
#define PDH_CSTATUS_ITEM_NOT_VALIDATED   0x800007D3
#define PDH_RETRY   0x800007D4
#define PDH_NO_DATA   0x800007D5
#define PDH_CALC_NEGATIVE_DENOMINATOR   0x800007D6
#define PDH_CALC_NEGATIVE_TIMEBASE   0x800007D7
#define PDH_CALC_NEGATIVE_VALUE   0x800007D8
#define PDH_DIALOG_CANCELLED   0x800007D9
#define PDH_CSTATUS_NO_OBJECT   0xC0000BB8
#define PDH_CSTATUS_NO_COUNTER   0xC0000BB9
#define PDH_CSTATUS_INVALID_DATA   0xC0000BBA
#define PDH_MEMORY_ALLOCATION_FAILURE   0xC0000BBB
#define PDH_INVALID_HANDLE   0xC0000BBC
#define PDH_INVALID_ARGUMENT   0xC0000BBD
#define PDH_FUNCTION_NOT_FOUND   0xC0000BBE
#define PDH_CSTATUS_NO_COUNTERNAME   0xC0000BBF
#define PDH_CSTATUS_BAD_COUNTERNAME   0xC0000BC0
#define PDH_INVALID_BUFFER   0xC0000BC1
#define PDH_INSUFFICIENT_BUFFER   0xC0000BC2
#define PDH_CANNOT_CONNECT_MACHINE   0xC0000BC3
#define PDH_INVALID_PATH   0xC0000BC4
#define PDH_INVALID_INSTANCE   0xC0000BC5
#define PDH_INVALID_DATA   0xC0000BC6
#define PDH_NO_DIALOG_DATA   0xC0000BC7
#define PDH_CANNOT_READ_NAME_STRINGS   0xC0000BC8

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.