正 文

摆脱DLL地狱的困扰之获取进程信息


www.7dspace.com  更新日期:2006-1-10 1:20:57  七度空间



  摘要

  本文讨论用各种不同的方法来获取系统中运行的进程信息,比如,进程列表,枚举列表中的进程,然后获取关于进程的详细信息。

  如何获取运行进程列表

  有三种方法来获取Win32运行进程的信息,参见表一:

  (表一)
方法 平台 备注
PSAPI Windows NT,Windows2000,Windows XP 获取进程,驱动器,模块,内存和工作集信息
性能计数器 Windows NT,Windows2000,Windows XP 提供除进程清单以外的关于进程的更多信息,可在远程机器上使用。
TOOLHELP32 Windows 9x,Windows2000,Windows XP 获取进程,线程,模块和堆信息

  本文不打算讨论 TOOLHELP32,因为 MSDN 中提供了很多使用 TOOLHELP32 函数的例子代码。性能计数器提供的信息更多,不仅仅是进程清单。如果你想获取远程机器的信息,那么性能计数器是再好不过的工具了。如果你总是想得到另外一台机器的进程列表信息,那么就用性能计数器吧!

  进程状态 API(PSAPI 全称是 Process Status API)是微软 SDK 中一个很有用的工具,在例子程序中有一个类 CProcessList,其实现文件 Process.cpp 对 PSAPI 进行了打包,用这个类可以获取进程清单。只要 Refresh 一被调用,通过某个进程的ID便可获得此进程的描述信息,并很容易用 GetFirst 和 GetNext 列举出其它进程:

   //用 CProcessList 列出运行进程
   // 一个挨一个获取进程
   CProcess* pProcess = NULL;
   POSITION  Pos = 0;
   for (
         pProcess = ProcessList.GetFirst(Pos);
         (pProcess != NULL);
         pProcess = ProcessList.GetNext(Pos)
       )
   {
      if (pProcess != NULL)
      {
      // 对进程信息进行处理
      }
   } 
  Refresh 的实现用到了 EnumProcesses 函数(在PSAPI中):
//刷新进程列表
void CProcessList::Refresh()
{
// 不要忘了重置和释放当前的进程列表
   DefaultReset();

// 存储当前进程列表
   DWORD aProcesses[MAX_PROCESS];
   DWORD cbNeeded = 0;

// 获取进程快照
   if (!g_PSAPI.EnumProcesses(aProcesses, sizeof(aProcesses), &cbNeeded))
      return;
   
// 计算返回了多少个进程IDs
   DWORD cProcesses = cbNeeded / sizeof(DWORD);

// 将CProcess 对象捆绑到每一个进程ID
   DWORD     dwProcessID;
   CProcess* pProcess;
   for (
         DWORD dwCurrentProcess = 0;
         dwCurrentProcess < cProcesses;
         dwCurrentProcess++
       )
   {
      dwProcessID = aProcesses[dwCurrentProcess];

   // 将进程信息添加到映射
      pProcess = new CProcess(TRUE);
      if (pProcess != NULL)
      {
      // 填写当前进程ID的进程信息--捆绑
         if (!pProcess->AttachProcess(aProcesses[dwCurrentProcess]))
            delete pProcess;
         else
         // 存到映射表中
            m_ProcessMap[(LPVOID)dwProcessID] = pProcess;
      }
   }

// 第二次循环需要知道此进程的子进程清单
   SetChildrenList();
}

  如果你至今还在支持 Windows 的 16 位代码,比如在任务管理器的 ntvdm.exe 项下列出的应用程序就属于此列,那么枚举进程更棘手。有关细节参见本文参考资料中的知识库文章,以及 Matt Pietrek 的专栏文章:August 1998 和 September 1998。
2页,页码:[1] [2] 

上一篇:摆脱DLL地狱困扰之目前的困境
下一篇:Photoshop制作宣纸底纹与墨韵特效
作者:NorthTibet编译  来源:VCKBASE ( 责任编辑:7dspace )
收藏此页】【打印】【关闭
站 内 搜 索
 

热 点 导 读
特 别 推 荐