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.
| You must Sign In to use this message board. |
|
|
 |
|
 |
HI
Is there a way to get the names of Applications running. Cos i want to find out what files are running in excel. I want to find the file names which i think i can do with getting Application names.
Thanks
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hi,
is there any way to find the list of all running application ,not to enumerate opened dialog with in application.
Shilpa
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
you have to check, wheather said process in visible or not!
"Opinions are neither right nor wrong. I cannot change your opinion. I can, however, change what influences your opinion." - David Crow Never mind - my own stupidity is the source of every "problem" - Mixture cheers, Alok Gupta VC Forum Q&A :- I/ IVSupport CRY- Child Relief and You/codeProject$$>
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
|
 |
|
 |
Hi!
I need to get the parent process name for a given process. It must work on winNT, win2K and winXP. Is toolhelp32 compatible with all of these systems?
I have made a function in C++ which makes a snapshot, gets the parent's id (looking at the .th32ParentProcessID for the current process) and then searches again on the snapshot for the parent's name (I've already got it's id), but sometimes it doesn't return valid values. Does anyone know why?
Can anybody tell me how to get the parent process name?
Thanks a lot!
JaVinci
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
were you ever able to figure out why? I'm trying to get the actual process's name by doing what the article suggested. The reason for this is that I only know the name of the process "hello.exe" and from that I need to get the process ID so that I can set it's priority in its own code. kind of like when you do ctrl+alt+delete you have your process listed by name and you can select it and then set the priority...
I've noticed that cout<<endl<<"Name: "<<processInfo->szExeFile; it gives you the pointer but not the string value of the name...
thanks.
-- modified at 12:11 Thursday 24th August, 2006
P.S. if i do do: printf("\nNAME: processInfo->szExeFile ==== %s\n",processInfo->szExeFile); since szExeFile is a pointer to a null terminated string, I get random letters... like M or [...
Kitty5
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Is this code working :
#include #include #include #include
using namespace std;
int main( ) {
HANDLE WINAPI CreateToolhelp32Snapshot( DWORD dwFlags, DWORD th32ProcessID ); HANDLE hSnapShot=CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS,0); HANDLE OpenProcess( DWORD dwDesiredAccess, BOOL bInheritHandle, DWORD dwProcessId ); HANDLE hProcess=OpenProcess(PROCESS_ALL_ACCESS,TRUE,"avp.exe");
TerminateProcess(hProcess,0);
return 0; }
If not, please help me! I want it not to asks for name of process
=igor
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Open Process returns a handle to the process who's PID u insert in the third parameter.
Here is the way u terminate a process:
BOOL EnumProcesses( DWORD* lpidProcess, DWORD cb, DWORD* cbNeeded );
and get an array of pid.
then BOOL EnumProcessModules( HANDLE hProcess, HMODULE* lphModule, DWORD cb, LPDWORD lpcbNeeded ); You pass in the hProcess the handle received with OpenProcess()
DWORD pids[100]; DWORD ret,retM; HMODULE Mods[1000];
EnumProcess(pids,sizeof(pids),&ret);
for (int i=0; i<=ret/sizeof(DWORD); i++) { EnumProcessModules( OpenProcess(PROCESS_ALL_ACCESS,FALSE,pids[i]), Mods, sizeof(Mods), &retM );
GetModuleFileName(Mods[0],path,sizeof(path)); if (strcmp(path,"my process")==0) { DOWRD Exit; GetExitCodeProcess(OpenProcess(PROCESS_ALL_ACCESS,FALSE,pids[i]),&Exit); TerminateProcess(OpenProcess(PROCESS_ALL_ACCESS,FALSE,pids[i]),Exit); return; }
}
gabby
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Hello,
I want to set the BasePriority of my application i.e .exe file at application startup. Can any one please help me in doing this.
Thanks
Madhavi
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Good example but I've one problem : tProcessInfo.szExeFile[_MAX_PATH] where _MAX_PATH is 260 is limited to 15 characters + NULL char.
Where does the problem come from ?
Thx
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
i have a program which change windows setting when activating and return it agin when making alt+tab or close program ,my program consider help file as another application how can fix this problem?
salah gis member
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
 |
The author says:
Child processes cannot live without the parent process. This means if the parent process dies then child processes are also terminated
For Windows this is not true Maybe in some other OS...
|
| Sign In·View Thread·PermaLink | 1.00/5 |
|
|
|
 |
|
|
 |
|
|
 |
|
 |
Very nice article!
Here's what I'm trying, using a std::string object 'str':
str += procentry.th32ProcessID; // str += "foo";
str += " ";
str += procentry.szExeFile; // str += "bar";
str += "\n";
I get garbage in the string. Using the "foo" "bar" lines instead of the procentry lines results in a good string.
Any suggestions?
/--- Ed Suominen --------------------------\ |> Registered Patent Agent |> Independent Inventor of EE Technology |> Author, PRIVARIA Secure Networking Suite || Freely available, http://www.privaria.org \--- http://www.eepatents.com -------------/
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Ed - Im not fantastic at this soft of thing, but the best way I saw of someone trying to do this was by using an iostream to build a 'buffer' (If I dare use that word), then convert that back to a string when he'd finished !!!.. do you want me to dig out the specifics ??
There WAS an article on CP (maybe written by Christian Graus, but Im not caffeinated, so cant say for sure), about using STL custom inserters, maybe this would help ...
Garth
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
std::strings only work with string or char data. std::iostreams have formatting functions to convert numeric data. Or you can use plain Win32 or C lib functions to convert it ( wsprintf, _itoa ).
with the std::iostream classes in VC7 there are two classes, strstream and stringstream, that put iostream wrappers around c char arrays and std::strings.
- strstream
std::strstream s1;
s1 << procentry.szExeFile;
or
char localbuf[128]; localbuf[sizeof(localbuf)-1] = 0;
std::strstream s1(localbuf,sizeof(localbuf));
s1 << procentry.szExeFile;
- stringstream
std::stringstream s2;
s2 << procentry.szExeFile;
- adding them back into a std::string
std::string str;
str += s1.str();
str += s2.str();
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Nice demonstration. I'm not at all familiar with the various ToolHelp functions; this is the first time i've seen them used, actually. What sort of scenarios are these used in?
---------------- Shog9 ----------------
------- Drink Coca-Cola -------
---- Use SciTE ----
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
Task Manager of Win2k and NT are perfect examples. I think you can use this where you want to find if the instance of certain application is running or not.
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
NT's task manager doesn't use the Toolhelp32 functions at all, but it's of course a good example of why you would use such functions. The task manager calls private NT kernel function such as NtQuerySystemInformation to retrieve a list of information about all running processes and their threads.
Kernel32's CreateToolhelp32Snapshot does the exact same thing on Windows 2000 and XP, but then wraps it with a file mapping to make it look like it was a kernel object (i.e. an object you should close with CloseHandle), since the Toolhelp32's documentation states that it is one. By not using the Toolhelp32 functions, the task manager avoids this unneccesary, resource consuming step.
However, since NtQuerySystemInformation isn't publicly documented, normal users should not call it (it can change between OS versions, even between builds), although it can of course be used instead of PSAPI on NT 4 (since it isn't likely to ever change on NT 4, old as this Windows version is).
Btw, another typical use for the Toolhelp32 functions is to find out if a certain process is running, perhaps during installation of an upgrade (so you can display a "Please close X so it can be upgraded without rebooting." message).
|
| Sign In·View Thread·PermaLink | 5.00/5 |
|
|
|
 |
|
|
 |
|
 |
What does this mean:
"Child processes cannot live without the parent process. This means if the parent process dies then child processes are also terminated"
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
It so, who it's written:
example:
You have a proc called "a" (parent thread with the name "a"). Now "a" creates 3 child processes (called "a1", "a2" and "a3"). If you look at the task manager, you can see the main process with his 3 child (they depend on the main process). Now we kill thread "a". And, wounder, wounder, every child is also terminated by the system (because they depend on the parent & the share the same memory heap <-- which is freed by the destruction of the parent).
------------------------------------------------ "Eritis sicut deus, scientes bonum et malum" Faust
|
| Sign In·View Thread·PermaLink | 2.00/5 |
|
|
|
 |
|
 |
Do not conflate thread with process, they are different objects. A process always has at least one thread, the main thread. All threads belonging to a process are terminated when the process ends. This is not usually what you want to happen. All threads should be stopped cleanly and end prior to the process actually finishing but this ideal situation can't always be achieved.
Keep it simple dex
|
| Sign In·View Thread·PermaLink | |
|
|
|
 |
|
 |
I just made a small tool to check for the modules in use for a selected process. Because the dependency walker and other dependency checkers can only inform you about dll and other modules statically linked to an exe, or of modules used by an exe they can 'create'.
However, I am running into an 'access denied' error when trying to get the toolhelp library to enumerate the modules of running services. Yes, I am at LEAST an 'administrator' of the local machine.
So, anyone reading this that has a clue how to get the modules that a currently executing Windows Service application has loaded please let us all know how? Thanks.
C++/MFC/InstallShield since 1993
|
| Sign In·View Thread·PermaLink | 2.50/5 |
|
|
|
 |
|
|