65.9K
CodeProject 正在变化。 阅读更多。
Home

进程、模块和线程枚举类

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.21/5 (9投票s)

2002年5月14日

Ms-PL

3分钟阅读

viewsIcon

172686

downloadIcon

5413

3个简单的类,用于轻松检索正在运行的进程、模块和线程

Sample Image - w32process.jpg

引言

你是否曾想过 Windows 任务管理器是如何实现的?这里有 3 个类供你参考。这些类实现了对所有正在运行的进程、所有已加载的模块(可执行文件和动态链接库)以及所有线程的枚举。

这些类派生自 MFC 类 CArray 或 STL 模板类 stl::vector。STL 实现不需要任何 MFC 组件,但支持最常用的 CArray 函数(GetSize()RemoveAll()operator[]、GetAt()),因此可以在任何使用 CArray 的地方使用它。你可以通过在预处理器设置中定义符号 USE_STL 来启用 STL 实现。

头文件将自动指示链接器使用适当的 lib 文件。所有类都使用了 Toolhelper Librarypsapi.lib 中的 Process Status Helper。你可以在 MSDN 上找到完整的文档。

请注意:为了使用 PSAPI,你必须安装 Platform SDK。有关使用 Toolhelp 和 PSAPI 的更多信息,请在此处 查看

这些类远未完善,还有很大的改进空间。商业应用程序需要更深入地研究进程处理相关的安全方面,但这超出了本文的范围。

枚举进程

使用 CProcessList 类,你可以获得正在运行的进程的完整集合。该类为你提供了所有进程的所有必要信息。

// lets get a list of all processes
CProcessList pl;
for(int i = 0; i < pl.GetSize(); ++i)
    TRACE("Process %s has %i threads\n", pl[i].szModule, pl[i].pe32.cntThreads);

CProcessList 派生自 CArray<PROCESS_INFORMATION_EX, PROCESS_INFORMATION_EX>(或 stl::vector<PROCESS_INFORMATION_EX>)。PROCESS_INFORMATION_EX 大致定义如下:

typedef struct _PROCESS_INFORMATION_EX
{
... some ctors...
    PROCESSENTRY32 pe32;                            // see tlhelp32.h
    PSID           pSid;                            // contains the owning user SID
    TCHAR          szModule[MAX_MODULE_NAME32 + 1]; // translated path+modulename
} PROCESS_INFORMATION_EX;

大部分信息来自 tlhelp32.h 中定义的 PROCESSENTRY32 结构。还包括拥有该进程的用户 SID 以及包含该进程代码的模块的真实名称。

pSid 成员可以轻松用于检索用户的全名和域。

SID_NAME_USE  use;
DWORD         dwName = 256;
DWORD         dwDomain = 256;
TCHAR         uname[256];
TCHAR         udomain[256];

if(LookupAccountSid(NULL, pl[i].pSid, &uname[0], &dwName, &udomain[0], &dwDomain, &use))
{
    TRACE("%s\\%s", &udomain[0], &uname[0]);
}

注意:对于商业应用程序,你将需要更多的代码,但对于家庭使用和演示来说,这已经足够了。

CProcessList 的析构函数负责正确释放所有分配的内存。请注意,SID 不能像结构那样复制。有关更多信息,请参阅 w32process.h 文件。

为了排除那些你没有访问权限(因为没有足够权限,例如系统进程)的进程,你可以在类的构造函数中使用可选的布尔参数。

枚举模块

由于大多数进程使用许多不同的模块,因此还有一个类用于枚举这些模块。CModuleList 也派生自集合模板类 CArray 或 vector,其中包含 tlhelp32.h 中定义的 MODULEENTRY32 结构。它基本上只是该结构的一个包装器。

当你将进程 ID 传递给构造函数时,它将枚举给定进程使用的所有已加载(!)的模块。默认构造函数枚举当前进程的模块。

请注意,模块列表在进程的生命周期内可能会发生变化,因为进程可能会动态加载和卸载 DLL。如果你想要准确的结果,必须创建一个 CModuleList 实例并立即使用它。

枚举线程

CThreadList 类是 w32process.h 中最后一个类,与其他类一样,它派生自集合模板 CArrayvector。它实现了 THREAD_INFORMATION_EX 结构,该结构定义如下:

typedef struct _THREAD_INFORMATION_EX
{
... some ctors...
    THREADENTRY32 te32;   // see tlhelp32.h
    CONTEXT       ctx;    // see winnt.h
} THREAD_INFORMATION_EX;

构造函数接受 2 个参数:进程 ID 和一个可选的布尔值。如果进程 ID 为 0,则枚举当前进程的线程。如果布尔参数为 true,则 ctx 成员将被填充为线程的上下文信息。这是相当特定的信息,因此默认情况下不包含。

需要注意的是,如果你需要上下文信息,该类必须暂时挂起每个线程才能获取上下文信息。

示例应用

示例应用程序展示了一个简单的进程列表,显示了基本的进程信息。当你选择一个进程时,你可以查看该进程的模块和线程。

兼容性

所有类都完全支持 MBCS/Unicode,并且可以作为 MFC CArray 派生类或 STL vector 派生类使用。在 VC7 下编写、编译和测试,但应也能在 VC6 及更早版本下编译。示例应用程序附带 STL、MFC 和 UNICODE 配置。

© . All rights reserved.