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
The STL implementation does not need any MFC components
but supports the most commonly used
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
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
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.
CProcessList class you get
the complete set of running processes. The class provides you
with all necessary information on all processes.
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
is roughly defined as
typedef struct _PROCESS_INFORMATION_EX
... some ctors...
TCHAR szModule[MAX_MODULE_NAME32 + 1];
The biggest part of information comes from
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.
pSid member can easily be used
to retrieve the full name and domain of the user:
DWORD dwName = 256;
DWORD dwDomain = 256;
if(LookupAccountSid(NULL, pl[i].pSid, &uname, &dwName, &udomain, &dwDomain, &use))
TRACE("%s\\%s", &udomain, &uname);
Note: For a commercial application you will need a bit
more code, but for home use and demonstration this is sufficient.
The destructor of
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.
Since most processes make use of many different
modules there is also a class to enumerate these.
also derived from one of the collection template classes
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
and immediately use it.
CThreadList class is the last of
the classes in w32process.h and is, like the others, derived
from the collection templates
vector. It implements
THREAD_INFORMATION_EX structure which is defined as:
typedef struct _THREAD_INFORMATION_EX
... some ctors...
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.
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.
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.