最近在写一个小项目,涉及到查找和结束进程树的功能实现,通过系统API能够获取到的信息有进程名,进程ID,父进程ID等,所以通过一个递归操作可以获取到一棵完整的进程树。但由于进程ID是系统随机给予的,并没有什么规律,所有最理想的做法是从最祖父进程(孤儿进程)开始查找子进程,再查找孙子进程…… 这种思路。
我的程序使用MFC对话框写的,具体效果如下图。
首先是进程信息存放的结构体
//进程结构体
typedef struct TASKMGRDLL_API tagProcessItem
{
DWORD dwProcessID; //进程ID
DWORD dwModuleID; //模块ID
HANDLE hProcess; //进程句柄
DWORD dwcntThreads; //线程数
DWORD dwParentProcessID;//父进程ID
string szExeFile; //进程文件名
string szExeFilePath; //进程文件全路径
BOOL bParentAvailableFlag;//父进程是否存在
int nProcTreeIndex; //进程树子孙标记
//模块列表
vector <ModuleItemA> theModuleList;
//拷贝函数
void CopyItemFrom(tagProcessItem &theItem)
{
this ->dwProcessID = theItem.dwProcessID;
this ->dwParentProcessID = theItem.dwParentProcessID;
this ->dwModuleID = theItem.dwModuleID;
this ->dwcntThreads = theItem.dwcntThreads;
this ->szExeFile = theItem.szExeFile;
this ->szExeFilePath = theItem.szExeFilePath;
this ->hProcess = theItem.hProcess;
this ->bParentAvailableFlag = theItem.bParentAvailableFlag;
this ->nProcTreeIndex = theItem.nProcTreeIndex;
this ->theModuleList = theItem.theModuleList;
}
void CopyItemTo(tagProcessItem &theItem)
{
theItem.dwProcessID = this ->dwProcessID;
theItem.dwParentProcessID = this ->dwParentProcessID;
theItem.dwModuleID = this ->dwModuleID;
theItem.dwcntThreads = this ->dwcntThreads;
theItem.szExeFile = this ->szExeFile;
theItem.szExeFilePath = this ->szExeFilePath;
theItem.hProcess = t