本文簡要介紹了如何使用 GetProcessTimes API 函數來獲取某個進程運行了多長時間。GetProcessTimes 函數返回的時間值很容易轉換成可讀和可利用的信息。參考如下代碼段:
HANDLE hProcess;
FILETIME ftCreation,
ftExit,
ftKernel,
ftUser;
GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
本文例子程序的運行界面如下圖所示:
計算運行的時間
某個進程運行的時間長度是指該進程創建的時間到當前時間逝去的時間。這個信息被存儲在 FILETIME 結構中。只要計算出逝去的時間,那麼再將它轉換成小時/分鐘/秒形式。很幸運,借助 COleDateTime 類,這個工作很容易完成。
COleDateTime timeNow = COleDateTime::GetCurrentTime(),
timeCreation = ftCreation;
COleDateTimeSpan timeDiff = timeNow - timeCreation;
在此你可以使用 COleDateTimeSpan 中不同的方法來獲得逝去的小時/分鐘等信息。
計算內核和用戶時間
參考相關文檔,內核和用戶時間就是實際逝去的時間。這個值在 FILETIME 結構中被表示為 100 納秒單位。將它轉換成可用的信息有兩種方法:
方法一:
我們可以用一些基本方法將它轉換成以秒為單位的值,一納秒相當於千萬分之一秒,因為這個時間已經用 100 納秒單位表示,所以用10個百萬來除一下即可:
__int64 i64Kernel = *((__int64 *) &ftKernel);
DWORD dwKernel = (DWORD) (i64Kernel / 10000000U);
除此之外,還可以使用聯合數據類型:
union
{
FILETIME ftKernel;
__int64 i64Kernel;
} timeKernel;
timeKernel.ftKernel = ftKernel;
DWORD dwKernel = (DWORD) (timeKernel.i64Kernel / 10000000U);
不管哪種方法,dwKernel 都表示內核模式的進程運行逝去的秒數。再把秒數轉換成小時/分鐘/秒的形式就不難了。
方法二:
第二種方法只需要調用一個 API 函數就能搞掂,這個 API 函數就是 FileTimeToSystemTime,該函數將結果存儲到 SYSTEMTIME 結構中,然後從結構中獲取 wHour、wMinute 和 wSecond 成員。
SYSTEMTIME stKernel;
FileTimeToSystemTime(&ftKernel, &stKernel);
用戶模式時間的獲取可以如法炮制。
總結
本文涉及的一些 API 函數調用如下:
GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
timeCreation = ftCreation;
strData.Format("Created at %02d:%02d:%02d", timeCreation.GetHour(),
timeCreation.GetMinute(), timeCreation.GetSecond());
timeDiff = timeNow - timeCreation;
strData.Format("Elapsed time = %ud %uh %um %us", timeDiff.GetDays(),
timeDiff.GetHours(), timeDiff.GetMinutes(),
timeDiff.GetSeconds());
FileTimeToSystemTime(&ftKernel, &stKernel);
strData.Format("Time in kernel mode = %uh %um %us", stKernel.wHour,
stKernel.wMinute, stKernel.wSecond);
需要說明的一點是本文所述方法不能獲取某些系統級進程的運行時間信息以及名稱。需要另想辦法實現。
本文配套源碼