在 Windows 程式設計中,了解某個進程已經運行了多久是常見需求。本文詳細介紹如何使用 GetProcessTimes API 函數獲取進程的創建時間、退出時間、內核模式時間和用戶模式時間,並示範如何將這些原始數據轉換為人類可讀的格式。
GetProcessTimes 函數原型如下:
BOOL GetProcessTimes(
HANDLE hProcess,
LPFILETIME lpCreationTime,
LPFILETIME lpExitTime,
LPFILETIME lpKernelTime,
LPFILETIME lpUserTime
);
該函數返回四個 FILETIME 結構,分別代表進程創建時間、退出時間、內核 CPU 時間和用戶 CPU 時間。所有時間均以 100 奈秒間隔為單位,自 1601 年 1 月 1 日起計算。
進程運行壽命 = 當前時間 - 進程創建時間。利用 MFC 的 COleDateTime 和 COleDateTimeSpan 類別可輕鬆完成換算:
COleDateTime timeNow = COleDateTime::GetCurrentTime();
COleDateTime timeCreation = ftCreation; // 隱含轉換
COleDateTimeSpan timeDiff = timeNow - timeCreation;
// 取得天、時、分、秒
int nDays = timeDiff.GetDays();
int nHours = timeDiff.GetHours();
int nMinutes = timeDiff.GetMinutes();
int nSeconds = timeDiff.GetSeconds();
內核/用戶時間同樣儲存在 FILETIME 中,單位同為 100 奈秒。提供兩種轉換方法:
利用 64 位整數直接除以 10,000,000(1 秒 = 107 × 100 奈秒):
__int64 i64Kernel = *(__int64*)&ftKernel;
DWORD dwKernelSec = (DWORD)(i64Kernel / 10000000Ui64);
或使用聯合體避免指針轉型:
union {
FILETIME ft;
__int64 i64;
} u;
u.ft = ftKernel;
DWORD dwKernelSec = (DWORD)(u.i64 / 10000000Ui64);
直接轉換為 SYSTEMTIME 結構,讀取 wHour、wMinute、wSecond:
SYSTEMTIME stKernel;
FileTimeToSystemTime(&ftKernel, &stKernel);
// stKernel.wHour, stKernel.wMinute, stKernel.wSecond 即為所需值
GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser);
COleDateTime timeNow = COleDateTime::GetCurrentTime();
COleDateTime timeCreation = ftCreation;
COleDateTimeSpan diff = timeNow - timeCreation;
CString str;
str.Format(_T("Elapsed: %ud %uh %um %us"), diff.GetDays(), diff.GetHours(), diff.GetMinutes(), diff.GetSeconds());
SYSTEMTIME stKernel, stUser;
FileTimeToSystemTime(&ftKernel, &stKernel);
FileTimeToSystemTime(&ftUser, &stUser);
str.Format(_T("Kernel: %02u:%02u:%02u User: %02u:%02u:%02u"),
stKernel.wHour, stKernel.wMinute, stKernel.wSecond,
stUser.wHour, stUser.wMinute, stUser.wSecond);
PROCESS_QUERY_LIMITED_INFORMATION 權限。ftExit 在進程仍在運行時通常為零。透過 GetProcessTimes 搭配 COleDateTime/FileTimeToSystemTime,即可輕鬆獲取並顯示進程的運行壽命與 CPU 佔用時間,適用於效能監控、診斷工具等場景。