Click here to Skip to main content
65,938 articles
CodeProject is changing. Read more.
Articles
(untagged)

Process, Module and Thread enumeration classes

15 May 2002 1  
3 simple classes for easy retrival of running processes, modules and threads

Sample Image - w32process.jpg

Introduction

Did you ever wonder how the Windows Taskmanager was implemented? Well, here are 3 classes to start with. The classes implement the enumeration of all running processes, all loaded modules (executables and dynamically loaded libraries) and also all threads.

The classes are derived from the MFC class CArray or the STL template class stl::vector. The STL implementation does not need any MFC components but supports the most commonly used CArray functions (GetSize(), RemoveAll(), operator[], GetAt()), so it can be used wherever a CArray is used. You can enable the STL implementation by defining the symbol USE_STL in the preprocessor settings.

The header file will automatically instruct the linker to use the appropriate lib files. All classes make use of the Toolhelper Library and the Process Status Helper in psapi.lib. You can find the whole documentation on MSDN.

Please note: you must have the Platform SDK installed in order to use PSAPI. More information on using Toolhelp and PSAPI can be found here

The classes are far from being complete, there is lot of space for improvements. A commercial application would need to delve a bit deeper into the security related aspects of process handling but this is out of the scope of this article.

Enumerating Processes

With the CProcessList class you get the complete set of running processes. The class provides you with all necessary information on all processes.

// 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 derives from CArray<PROCESS_INFORMATION_EX, PROCESS_INFORMATION_EX> (or stl::vector<PROCESS_INFORMATION_EX>). PROCESS_INFORMATION_EX is roughly defined as

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;

The biggest part of information comes from the PROCESSENTRY32 structure defined in tlhelp32.h. Also included are the SID of the user owning the process and the real name of the module which contains the code for this process.

The pSid member can easily be used to retrieve the full name and domain of the user:

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]);
}

Note: For a commercial application you will need a bit more code, but for home use and demonstration this is sufficient.

The destructor of CProcessList takes care of correctly freeing all allocated memory. Just be aware that the SID cant be copied like a structure. See the w32process.h file for more information.

To exclude processes to which you don't have access because you don't have sufficient privileges (system processes) you can use the optional boolean parameter in the constructor of the class.

Enumerating Modules

Since most processes make use of many different modules there is also a class to enumerate these. CModuleList is also derived from one of the collection template classes CArray or vector containing the MODULEENTRY32 structure defined in tlhelp32.h. Its basically just a wrapper around the structure.

When you pass a process ID to the constructor it will enumerate all loaded(!) modules used by the given process. The default constructor enumerates the modules of the current process.

Please be aware that the module list may change during the lifetime of the process because the process may dynamically load and unload DLL's. If you want accurate results you must create a instance of CModuleList and immediately use it.

Enumerating Threads

The CThreadList class is the last of the classes in w32process.h and is, like the others, derived from the collection templates CArray or vector. It implements the THREAD_INFORMATION_EX structure which is defined as:

typedef struct _THREAD_INFORMATION_EX
{
... some ctors...
    THREADENTRY32 te32;   // see tlhelp32.h

    CONTEXT       ctx;    // see winnt.h

} THREAD_INFORMATION_EX;

The constructor takes 2 arguments: the process ID and a optional boolean. If the process ID is 0 it enumerates the threads of the current process. If the boolean parameter is true, the ctx member will be filled in with the threads context information. This is rather specific information so it is excluded by default.

Important to note is that if you need context information, the class must temporarily suspend each thread to obtain the context information.

Sample Application

The sample application represents a simple process list, showing basic process information. When you select a process, you can view the processes modules and threads.

Compatibility

All classes are fully MBCS/Unicode enabled and can be used either MFC CArray derived or STL vector derived. Written, compiled and tested under VC7 but should also compile with VC6 and below. The sample application comes with STL, MFC and UNICODE configurations.

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here