Enumerating Running Processes in Win95 and WinNT


Overview

While developing an application, I encountered the need to get a list of all running processes (programs). Ok, so all advanced Win32 programmers know that for such a task one uses the performance data in WinNT or the ToolHelp functions in Win95. BUT, In my case my application had to run both under NT and 95, without conditional compilation, i.e without having two seperate versions of the executable, one for win95 and one for NT. So, to solve this problem I wrote a C++ class, calles Win32Process that gets a list of all currently running applications, in a "platform independent" way (independent between windows 95 and NT, and of course it's using MFC, that's why I put it in quotes). More accuratly, the class detects if its running under NT or 95, and accordingly invokes the correct functions.

More-Over, the code for the class is written in such a way, that when platform-dependent functions from a dll are used, these functions are loaded dynamically, so that you do not have to link statically to a .lib file, thereby making your code (or at least your project settings) different if compiling on NT or on 95. for instance, if we are compiling on NT, but we need to use the Win 95-specific ToolHelp function Process32Next( ), there is no problem - the project will compile, link and run successfully.

So, in summary, all you need to do is drop this class into your current VC++ 5.0 project - without changing ANY of your current project settings, and then you'll be able to enumerate all running processes without worrying if the code will be executed/compiled on win95 or NT. The class will automatically do this for you.

Using Win32Process.cpp

To use this class, include it's header where you want to use it. Then, instantiate it:

Win32Process m_win32proc;

Then, before using it (for example in OnInitDialog of you application), Initiate it:

if(!m_win32proc.Init())
	AfxMessageBox(m_win32proc.GetLastError());

The initiation gets the needed function pointers if running on 95. If running on NT it doesnt do much but still must be called.
Note that EVERY method returns false if it fails and true if it succeeds, and to get the cause of the error you simply call
GetLastError( ), in return for which you get a CString describing the nature of the error.

Now, to get a list of all the processes, do:

if (!m_win32proc.EnumAllProcesses())
{
	AfxMessageBox(m_win32proc.GetLastError());
	return;
} 

And you're all set! Now a CStringArray member in Win32Process.cpp contains all the names of the currently running processes.
(Note that the AfxMessageBox is just for debugging. When actually using it you may do anything you like with the error string. (BTW I havent had an error yet using this class)).

To display these names (for example in a list box) you may do something like this:

//populate the list box
int size=m_win32proc.GetAllProcessesNames()->GetSize();
for (int i=0;i<size;i++)
	m_ctrlProcLB.AddString(m_win32proc.GetAllProcessesNames()->GetAt(i));

Where the m_ctrlProcLB is a list box in this case. (See the enclosed Demo)
Simple, isnt it? and remember that you use the same code regardless if its running on NT or 95. Also, none of your project settings have to be changed.

It is also possible to check if one certain process is running using the member GetProcessStatus( ) as follows:

if (!m_win32proc.GetProcessStatus(&m_strProcessToCheck,&bStatus))
{
	AfxMessageBox(m_win32proc.GetLastError());
	return;
}
if (bStatus)
	AfxMessageBox(m_strProcessToCheck+" is running!");
else	
	AfxMessageBox(m_strProcessToCheck+" is NOT running!");

Note that GetProcessStatus( ) does not return TRUE if the process is running, but rather, it returns TRUE if it was successful. You get the info about the process by passing a pointer to a boolean (see bStatus above)

The Demo

Enclosed is also a demo program that exemplifies the usage of this class. The demo is a simple VC++ 5.0 project. The demo also shows how you can test whether a specific process is running, using the Win32Process class.

To use the class, copy the file Win32Process.cpp and Win32Process.h from the demo directory into your project directory, and add them to your project.

Download Source Code and Example- 107KB

Last updated: 27 June 1998 


Comments

  • Checked processes on remote pc`s

    Posted by Legacy on 11/18/2002 12:00am

    Originally posted by: Aleksandar

    Could you help me how to do the same think , but on the remote compiuters. I mean how to make a list of all active process and how to chek if some of them are active or not. The problem is because are processes on remote compiuters, so the classes are OK but may I use it on remote compiuters.
    
    Thanks in advance.
    Aleksandar.

    Reply
  • Nice, but...

    Posted by Legacy on 07/19/2002 12:00am

    Originally posted by: Jackrabbit

    This *is* nice, but... what if I'd like to know precisely when a process has finished (assuming I know it's active)? It's damned expensive to iteratively check the activity...

    Thanks

    Reply
  • It Doesn't pick up 16 bit apps that are running!

    Posted by Legacy on 12/07/1999 12:00am

    Originally posted by: ken

    Any ideas?

    Reply
  • exactly what i needed

    Posted by Legacy on 06/15/1999 12:00am

    Originally posted by: casey boone

    i was looking for a way to get all the currently running programs and this fits the bill perfectly.

    Reply
  • Kill NT process?

    Posted by Legacy on 05/13/1999 12:00am

    Originally posted by: FW

    How can we get the process handles in Win NT 4.0, so we can kill them also with TerminateProcess()?

    Reply
  • Adding a function to kill processes

    Posted by Legacy on 03/22/1999 12:00am

    Originally posted by: Raphael Phan

    Hi,
    
    

    I think the win32process class is great. However, we could
    also include a function to kill processes.

    Define an array of DWORDS for the process ID
    CDWordArray m_PIDArray;

    next, include a few lines in the FindProcesses95() function
    to add the names of running processes in a string array

    PROCESSENTRY32 process;
    process.dwSize=sizeof(PROCESSENTRY32);

    BOOL bContinue=m_p_fnProcess32First(handle,&process);
    m_PIDArray.Add(process.th32ProcessID); //ADD LINE HERE

    while(bContinue)
    {
    if (!bJustCheckingOne) //do we want to enumerate all processes, or do we just wanna check if one is active?
    {
    m_strArray.Add(ExtractProcessName(process.szExeFile)); //Path and filename of the executable file for the process
    }
    else
    {

    if ((*ProcessName)==ExtractProcessName(process.szExeFile))
    {
    CloseHandle(handle);
    m_bActive=true;
    return true;
    }
    }
    bContinue=m_p_fnProcess32Next(handle,&process);
    m_PIDArray.Add(process.th32ProcessID); //ADD LINE HERE
    }

    and then include the function that returns the ID of the
    process highlighted in the list box. The parameter passed
    to this function is the name of the highlighted process

    DWORD Win32Process::GetPID(CString procKill)
    {
    int index;
    for (int i=0;i<m_strArray.GetSize();i++)
    {
    if (procKill==m_strArray.GetAt(i))
    index=i;
    }
    return m_PIDArray.GetAt(index);
    }

    That is all we need to add to the class. To use it, we could
    add a button to the proctest dialog box, and include a message
    handler in our main program

    CMainProgram::OnKill()
    {
    int index=m_ctrlProcLB.GetCurSel();
    if (index!=LB_ERR)
    {
    CString procKill;
    m_ctrlProcLB.GetText(index,procKill);
    if (procKill.CompareNoCase("explorer")==0)
    AfxMessageBox("Not allowed to terminate the default Explorer ");
    else
    {
    HANDLE process;
    DWORD PID;
    PID=m_win32proc.GetPID(procKill);
    process = OpenProcess(PROCESS_TERMINATE, 0, PID);
    TerminateProcess(process, (unsigned)-1);
    m_ctrlProcLB.DeleteString(index);
    }
    }
    else
    AfxMessageBox("Please select a process to terminate");
    }

    Raphael

    Reply
Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Java developers know that testing code changes can be a huge pain, and waiting for an application to redeploy after a code fix can take an eternity. Wouldn't it be great if you could see your code changes immediately, fine-tune, debug, explore and deploy code without waiting for ages? In this white paper, find out how that's possible with a Java plugin that drastically changes the way you develop, test and run Java applications. Discover the advantages of this plugin, and the changes you can expect to see …

  • Packaged application development teams frequently operate with limited testing environments due to time and labor constraints. By virtualizing the entire application stack, packaged application development teams can deliver business results faster, at higher quality, and with lower risk.

Most Popular Programming Stories

More for Developers

Latest Developer Headlines

RSS Feeds