编程获取系统中各进程的时间信息

需要源代码Email向我所取。

Windows的任务管理器,可以用来查看当前系统中运行的进程信息,这些信息包括进程的名称、IDCPU占用率、占用CPU的时间以及占用内存的情况。有的时候,比如出于安全的考虑,可能希望了解关于某个进程的时间信息,比如进程创建的时间、进程已经运行了多长的时间、进程的内核模式占用时间和进程在用户模式的使用时间等。这时候,进程管理器就显得无能为力了。下面说说利用VC++编程实现获取系统中各进程时间信息的方法。实例完成后的运行效果如下图所示。

关键技术

首先介绍本实例将要用到的几个关键技术。

技术一、GetProcessTimes函数的使用

利用函数GetProcessTimes,能够获取指定进程的四种时间信息,将这些时间信息转换成可读的字符串后进行显示,就可以实现本实例的关键功能。下面的代码片段说明了使用GetProcessTimes的具体方法。

HANDLE hProcess;

FILETIME ftCreateing,

ftExit,

ftKernel,

ftUser;

GetProcessTimes(hProcess,&ftCreateing,&ftExit,&ftKernel,&ftUser);

技术二、计算运行时间

进程的运行时间实际上是一个时间段,即从该进程创建的时间到当前时间的间隔段。计算这个时间段原本比较麻烦,因为它带来了对时间对象进行时、分、秒的转换问题。幸运的是,COleDataTime类为程序设计带来了极大的方便。该类的一个应用代码片段如下:

ColeDataTime timeNow = ColeDataTime::GetCurrentTime();

TimeCreation = ftCreation;

ColeDataTimeSpan timeDiff = timeNow – timeCreation;

这样,开发人员就可以使用COleDataTimeSpan所提供的许多方法来获取时、分、秒等信息。

技术三、计算核心时间和用户时间。

进程在Windows操作系统下运行通常具有两种模式,一种是内核模式(KernelLevel 0),另一种是用户模式(UserLevel 3)。进程往往在这两种模式之间来回切换。实例开发遇到的问题是,获取该时间保存在FILETIME结构中是以千万分之一秒为单位进行计数的。这给程序进行信息的显示带来了困难。解决的方法有两个,分别介绍如下。

方法一、使用一些基本的算术将数据转换为秒单位。比如:

__int64 i64Kernel == *((__int64 *) &ftKernel);

DWORD dwKernel = (DWORD) (i64Kernel / 10000000U);

可以通过定义下面的联合体来方便编程:

union

{

FILETIME ftKernel;

__int64 i64Kernel;

}timeKernel;

timeKernel.ftKernel = ftKernel;

DWORD dwKernel = (DWORD) (timeKernel.i64Kernel / 10000000U );

方法二、使用FileTimeToSystemTime API函数。该函数将转换的结构保存到一个SYSTEMTIME结构中,其成员变量wHourwMinutewSecond即为转换后的数据信息。示例代码片段如下:

SYSTEMTIME stKernel;

FileTimeToSystemTime(&ftKernel , &stKernel);

用户模式时间的转换与上述方法相同。

关键实现代码

下面给出实例实现的关键代码。实例基于对话框创建,使用列表框进行信息的显示,代码中m_lcProcessInfo即为列表框控制对象。

用户列举进程时间信息的函数Process(),具体代码如下。

void CProcessTimeDlg::Process()

{

DWORD dwProcessIDs[150],dwSize,dwNeeded;

HANDLE hProcess;

HMODULE hModuleHandle;

FILETIME ftCreation,ftExit,ftKernel,ftUser;

SYSTEMTIME stKernel,stUser;

CString strName,strData;

int nIndex,nProcessCount,nItem;

COleDateTime timeCreation,timeNow;

COleDateTimeSpan timeDiff;

if (EnumProcesses(dwProcessIDs, sizeof(dwProcessIDs), &dwSize) == TRUE)

{

timeNow = COleDateTime::GetCurrentTime();

nProcessCount = dwSize / sizeof(DWORD);

for (nIndex = 0; nIndex < nProcessCount; nIndex++)

{

hProcess = OpenProcess(PROCESS_VM_READ | PROCESS_QUERY_INFORMATION, FALSE, dwProcessIDs[nIndex]);

if (NULL != hProcess)

{

strData.Format("%X", dwProcessIDs[nIndex]);

nItem = m_lcProcessInfo.InsertItem(nIndex, strData);

if (EnumProcessModules(hProcess, &hModuleHandle, sizeof(hModuleHandle), &dwNeeded) == TRUE)

{

if (GetModuleBaseNames(hProcess, hModuleHandle, strName) > 0)

{

m_lcProcessInfo.SetItemText(nItem, 1, strName);

if (GetProcessTimes(hProcess, &ftCreation, &ftExit, &ftKernel, &ftUser) == TRUE)

{

timeCreation = ftCreation;

strData.Format("%02d/%02d/%d - %02d:%02d:%02d",

timeCreation.GetMonth(),

timeCreation.GetDay(),

timeCreation.GetYear(),

timeCreation.GetHour(),

timeCreation.GetMinute(),

timeCreation.GetSecond());

m_lcProcessInfo.SetItemText(nItem, 2, strData);

timeDiff = timeNow - timeCreation;

strData.Format("%ud,%uh,%um,%us", timeDiff.GetDays(), timeDiff.GetHours(), timeDiff.GetMinutes(), timeDiff.GetSeconds());

m_lcProcessInfo.SetItemText(nItem, 3, strData);

FileTimeToSystemTime(&ftKernel, &stKernel);

strData.Format("%uh,%um,%us", stKernel.wHour, stKernel.wMinute, stKernel.wSecond);

m_lcProcessInfo.SetItemText(nItem, 4, strData);

FileTimeToSystemTime(&ftUser, &stUser);

strData.Format("%uh,%um,%us", stUser.wHour, stUser.wMinute, stUser.wSecond);

m_lcProcessInfo.SetItemText(nItem, 5, strData);

}

else

TRACE("GetProcessTimes() failed: %s\n", GetErrorMessage());

}

else

TRACE("GetModuleBaseName() failed: %s\n", GetErrorMessage());

}

else

TRACE2("EnumProcessModules() failed on PID %#x: %s\n", dwProcessIDs[nIndex], GetErrorMessage());

CloseHandle(hProcess);

}

else

TRACE2("OpenProcess(%#x) failed: %s\n", dwProcessIDs[nIndex], GetErrorMessage());

}

}

else

TRACE("EnumProcesses() failed: %s\n", GetErrorMessage());

}

用于返回错误信息的函数GetErrorMessage(),具体实现代码如下。

CString CProcessTimeDlg::GetErrorMessage()

{

CString strError;

LPVOID lpMsgBuf;

FormatMessage(

FORMAT_MESSAGE_ALLOCATE_BUFFER |

FORMAT_MESSAGE_FROM_SYSTEM |

FORMAT_MESSAGE_IGNORE_INSERTS,

NULL,

GetLastError(),

MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT),

(LPTSTR) &lpMsgBuf,

0,

NULL);

strError = (LPTSTR) lpMsgBuf;

LocalFree(lpMsgBuf);

return (strError);

}

返回指定模块基本名称的函数GetModuleBaseNames(),具体实现代码如下。

DWORD CProcessTimeDlg::GetModuleBaseNames(const HANDLE hProcess, const HMODULE hModule, CString &strName)

{

DWORD dwLength;

dwLength = ::GetModuleBaseName(hProcess, hModule, strName.GetBuffer(MAX_PATH), MAX_PATH);

strName.ReleaseBuffer();

return (dwLength);

}

以上就是实例的关键实现代码,使用时直接调用Process函数即可。注意先在自己的项目中包含psapi.h头文件。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值