Introduction
First of all, welcome to my tutorial "Enumerating Processes: A Practical Approach". Here, I will
try to define what a process is and then we will use C++ and the ToolHelp32 API to find out currently running processes
in our system.
What is a Process
A process is actually an instance of a running application. A system can have more than one
instance of same application all running independently. A process can initiate a subprocess, which is called child process
and the initiator process is sometimes referred to as a parent process. It is not like object-oriented
inheritance where we can make instances of a child class without making instances of
the parent class. Here
parent process will be created first and then child processes and a child process can share some resources
with parent process. Child processes cannot live without the parent process. This means if
the parent process dies
then child processes are also terminated.
Explanation
I am using Visual C++ 6.0 Professional Edition and project type is
Win32 Console Application (for simplicity). We will use functions from ToolHelp32 group of API. I am
using Win2000 and hope it will work on Win9x as well. For WinNT we use PSAPI (Process Status API) functions
and here we will not discuss them.
Now first we will include all necessary header files.
#include <windows.h>
#include <tlhelp32.h>
#include <iostream>
#include <string>
using namespace std;
int main( )
{
cout<<endl<<"Running Processes"<<endl;
Now we will take snapshot of currently running processes in our system
using CreateToolhelp32Snapshot()
function which returns handle to snapshot and it
contains information about running processes. Its prototype is:
HANDLE WINAPI CreateToolhelp32Snapshot(
DWORD dwFlags,
DWORD th32ProcessID
);
In dwFlags
we will use TH32CS_SNAPPROCESS
and 0
for th32ProcessID
. For other options see MSDN.
HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0);
Now we have information about all running processes in hSnapShot
. We will extract data
of each process from hSnapShot
and put it into PROCESSENTRY32
structure, which represents
a process, and it is a part of ToolHelp32 API. This extraction is done by using Process32First()
and Process32Next()
functions. Here we will only
use Process32Next()
function and it�s prototype is:
BOOL WINAPI Process32Next(
HANDLE hSnapshot,
LPPROCESSENTRY32 lppe
);
PROCESSENTRY32* processInfo=new PROCESSENTRY32;
We must set size of PROCESSENTRY32
structure in dwSize
member.
processInfo->dwSize=sizeof(PROCESSENTRY32);
int index=0;
Here we are passing snapshot handle and PROCESSENTRY32
structure
to Process32Next()
function. After execution, PROCESSENTRY32
structure
will contain information about a process. We are iterating through a loop until we
got FALSE
and this means there is now no process left to visit in snapshot and our pointer
is at the end of snapshot.
while(Process32Next(hSnapShot,processInfo)!=FALSE)
{
cout<<endl<<"***********************************************";
cout<<endl<<"\t\t\t"<<++index;
cout<<endl<<"***********************************************";
cout<<endl<<"Parent Process ID: "<<processInfo->th32ParentProcessID;
cout<<endl<<"Process ID: "<<processInfo->th32ProcessID;
cout<<endl<<"Name: "<<processInfo->szExeFile;
cout<<endl<<"Current Threads: "<<processInfo->cntThreads;
cout<<endl<<"Current Usage: "<<processInfo->cntUsage;
cout<<endl<<"Flags: "<<processInfo->dwFlags;
cout<<endl<<"Size: "<<processInfo->dwSize;
cout<<endl<<"Primary Class Base: "<<processInfo->pcPriClassBase;
cout<<endl<<"Default Heap ID: "<<processInfo->th32DefaultHeapID;
cout<<endl<<"Module ID: "<<processInfo->th32ModuleID;
}
Don�t forget to close handle.
CloseHandle(hSnapShot);
cout<<endl;
cout<<endl<<"***********************************************";
cout<<endl<<endl;
Now we will have all information about running processes including process ID (very important),
file name, parent process ID etc. We can get handle of any running process
by using OpenProcess()
function.
HANDLE OpenProcess(
DWORD dwDesiredAccess,
BOOL bInheritHandle,
DWORD dwProcessId
);
For description use MSDN.
int processID;
cout<<"Enter ProcessID to get handle of the process: ";
cin>>processID;
Here we are trying to get all possible access.
HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,processID);
if(hProcess==NULL)
{
cout<<"Unable to get handle of process: "<<processID;
cout<<"Error is: "<<GetLastError();
return 1;
}
Now we have handle of a process and we can do all types of magical things. Here we are getting priority
value of process using GetPriorityClass()
function and then setting priority to high
using SetPriorityClass()
function.
cout<<endl<<"Priority Class: "<<GetPriorityClass(hProcess);
SetPriorityClass(hProcess,HIGH_PRIORITY_CLASS);
CloseHandle(hProcess);
Now we are terminating process using TerminateProcess()
function.
cout<<endl<<"Enter Process ID to terminate that process: ";
cin>>processID;
hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,processID);
if(hProcess==NULL)
{
cout<<"Unable to get handle of process: "<<processID;
cout<<"Error is: "<<GetLastError();
}
TerminateProcess(hProcess,0);
When we create object on heap using new
operator it is necessary to explicitly delete
them using delete
.
delete processInfo;
return 0;
}
Conclusion
In this tutorial I have tried to explain how to get information about running
processes using C++. If you have any comments or question please email me.