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

Enumerating processes : A practical approach

0.00/5 (No votes)
6 Sep 2002 1  
Enumerating processes using ToolHelp32 library and also shows how to change priority and terminate a process.

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,  // access flag

        BOOL bInheritHandle,    // handle inheritance option

        DWORD dwProcessId       // process identifier

    );

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.

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