Link to home
Start Free TrialLog in
Avatar of dumpsterdivingdave
dumpsterdivingdave

asked on

Get current running processes.

How do you get a list of all the currently running processes on a computer?

I am writing an app that gets the list, and compares it to a pre-made list of processes (list of strings).  If the name of the process exists in both lists, it kills the process that is running and continues checking each running process to see if it should be killed.

I know how to accomplish this in VB .NET, but wanted to do this in C++ for speed reasons.
Avatar of mahesh1402
mahesh1402
Flag of India image

Refer this links about gettting current running processes using C++ :

http://www.codeproject.com/threads/processes.asp
http://www.codeguru.com/Cpp/W-P/win32/article.php/c1419

also all articles related processes : http://www.codeproject.com/threads/#Processes

MAHESH
Avatar of Jase-Coder
Jase-Coder

hi,
try this: I wrote this in builder but it should work in VC++


BOOL EnumWindowsProc(HWND hWnd, long lParam)
{
     char Buff[255], NameOfClass[255];

     GetWindowText(hWnd, Buff, 254);
     GetClassName(hWnd, NameOfClass, 254);
     cout << "Window Text: " << Buff << "\t" << "Class Name: "
           << NameOfClass << endl;

     return TRUE;
}

int main(int argc, char* argv[])
{
     EnumWindows((WNDENUMPROC)EnumWindowsProc, 0);
     cin.ignore();
     return 0;
}
@Jase-Coder

above given code will Enumerate current 'WINDOWS' and NOT ''PROCESSES''......PROCESSES can be hidden and not necessarily having windows....as author is looking for list of current 'Processes'........

MAHESH
Ok, You can use EnumProc instead here is a code example from the MSDN help

#include <windows.h>
#include <stdio.h>
#include <tchar.h>
#include "psapi.h"

void PrintProcessNameAndID( DWORD processID )
{
    TCHAR szProcessName[MAX_PATH] = TEXT("<unknown>");

    // Get a handle to the process.

    HANDLE hProcess = OpenProcess( PROCESS_QUERY_INFORMATION |
                                   PROCESS_VM_READ,
                                   FALSE, processID );

    // Get the process name.

    if (NULL != hProcess )
    {
        HMODULE hMod;
        DWORD cbNeeded;

        if ( EnumProcessModules( hProcess, &hMod, sizeof(hMod),
             &cbNeeded) )
        {
            GetModuleBaseName( hProcess, hMod, szProcessName,
                               sizeof(szProcessName)/sizeof(TCHAR) );
        }
    }

    // Print the process name and identifier.

    _tprintf( TEXT("%s  (PID: %u)\n"), szProcessName, processID );

    CloseHandle( hProcess );
}

void main( )
{
    // Get the list of process identifiers.

    DWORD aProcesses[1024], cbNeeded, cProcesses;
    unsigned int i;

    if ( !EnumProcesses( aProcesses, sizeof(aProcesses), &cbNeeded ) )
        return;

    // Calculate how many process identifiers were returned.

    cProcesses = cbNeeded / sizeof(DWORD);

    // Print the name and process identifier for each process.

    for ( i = 0; i < cProcesses; i++ )
        PrintProcessNameAndID( aProcesses[i] );
}
Ok ,
As said above on link  u may Also use Process32First() / Process32Next() to get extended info about processes such as Parent Process ID, Process ID,Name,
Current Threads,Current Usage,Flags,Size,Primary Class Base,Default Heap ID,Module ID etc.

http://www.codeproject.com/threads/processes.asp <===

>>If the name of the process exists in both lists, it kills the process that is running and continues checking each running process to see if it should be killed.

This one will be useful to kill Process by 'NAME' : http://www.codeproject.com/threads/killprocess.asp <==

MAHESH
Avatar of dumpsterdivingdave

ASKER

Seems like a TON of code just to kill a process.  If it helps, I only need to run this program on windows XP.  Heres the code that I have in VB .NET 2005 that works, so I'm looking for something as simple as possible.

Public Sub KillProcs()
     Dim Proc() as Process
     Dim p as Process

     Proc.GetProcesses()

     For Each p in Proc()
          If p.ProcessName.Contains("Name of Process") Then          'This would be repeated for each process that needed to be killed
               p.kill()
          End If
     Next
End Sub

Thats what the VB code looks like, and it works,  When I checked the included MSDN library for VC++ .NET 2005, to get a list of processes it gave me this:
 
public:
                   array<Process^>^localAll = Process::GetProcesses();

Which should get all of the processes running on the local computer and place them in the array (which is what the VB example above does).  I'm just not sure how to go through that array and check it against my list.

Visual C++ .NET 2005 does have the same kill command as VB .NET, (Process::Kill()).  How would I use this and keep the code more compact than previous examples?  There has to be a way, there can't be THAT much code involved.
I've increased the points to 350...
If you're going to rely on the same calls in Visual C++ .Net that you're using in VB.Net, I seriously doubt if you'd see any speed difference between the two.  

I'm not sure how you're doing things, but based on what you posted it looks like you're iterating over your array and generating a process list each time.  If that's what you're actually doing, you can increase the efficiency significantly if you do things differently.  Hash your current process list and then just check if the hash contains the name you want to kill.  Here's a Visual C++.Net version of that:

#include "stdafx.h"

#using <mscorlib.dll>

using namespace System;
using namespace System::Diagnostics;
using namespace System::Collections;


Hashtable* GetProcessListAsHash();

int _tmain()
{
      System::Collections::Hashtable* hProcessList = GetProcessListAsHash();

      String*      killList[] = {"notepad", "winword"};
      Process* processToKill;

      for (int i=0; i < killList->GetLength(0); i++)
      {
            String* lower = killList[i]->ToLower();
            if (hProcessList->ContainsKey(lower))
            {
                  ArrayList* processes = dynamic_cast<ArrayList*>(hProcessList->get_Item(lower));
                  IEnumerator* p = processes->GetEnumerator();
                  while (p->MoveNext())
                  {
                        processToKill = dynamic_cast<Process*>(p->Current);
                        Console::WriteLine("Killing {0} process id {1}", killList[i], __box(processToKill->get_Id()) );
                        processToKill->Kill();

                  }
            }
      }
}

Hashtable* GetProcessListAsHash()
{
      Hashtable* h = new System::Collections::Hashtable();
      IEnumerator* process = Process::GetProcesses()->GetEnumerator();
      Process* p;

      while (process->MoveNext())
      {
            p = dynamic_cast<Process*>(process->Current);
            String* processName = p->get_ProcessName()->ToLower();
            if (h->Contains(processName))
            {
                  ArrayList* list = dynamic_cast<ArrayList*>(h->get_Item(processName));
                  list->Add(p);
            }
            else
            {
                  ArrayList* list = new System::Collections::ArrayList();
                  list->Add(p);
                  h->Add(processName, list);
            }

      }

      return h;
}
ASKER CERTIFIED SOLUTION
Avatar of PockyMaster
PockyMaster
Flag of Netherlands image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial