In previous post I constructed a menu driven application for use with the serial debug port.  In that I called ShowRunningProcess() which I promised to define later.  The following defines that and uses the ToolHelpAPI to get the list of running processes.  As I review this, it does look like I need to update it for Windows CE 6.0, I will point out where below.

ShowRunningProcesses is simple, but that is only because it calls on other functions to do the work of getting the process list.  Since it is fairly basic, I won't go into in much.

void ShowRunningProcesses()
{
 PROCESSENTRY32 *CurrentProcess;
 // This won't work so well in CE 6.0 where the maximum number of processes is
 // Much greater than 32.
 PROCESSENTRY32 Process[ MAX_PROCESSES ];
 DWORD ProcessCount;
 DWORD index ;
 DWORD MaxProcessNameLength;
 // Get the list of running processes
 ProcessCount = GetRunningProcesses( Process );
 // Get the length of the longest process name so that we can format
 // the output to be pretty
 MaxProcessNameLength = GetMaxProcessNameLength( Process, ProcessCount );
 // Output a header to describe each column
 RETAILMSG( 1,(TEXT("%-*s %8s %13s %9s %9s %10s\n"),
     MaxProcessNameLength, TEXT("Process"),
     TEXT("PID"),
     TEXT("Base Priority"),
     TEXT("# Threads"),
     TEXT("Base Addr"),
     TEXT("Access Key")
     )) ;
 // Output information for each running process
 for( index = 0; index < ProcessCount; index++ )
 {
  CurrentProcess = &(Process[ index ] );
  RETAILMSG(1, ( TEXT("%-*s %8X %13d %9d %9X %10X\n"),
    MaxProcessNameLength, CurrentProcess->szExeFile,
    CurrentProcess->th32ProcessID,
    CurrentProcess->pcPriClassBase,
    CurrentProcess->cntThreads,
    CurrentProcess->th32MemoryBase,
    CurrentProcess->th32AccessKey
    ));
 }
}

GetRunningProcesses() is much more intersting.  This uses the ToolHelpAPI to enumerate all of the running processes, puts them in the process list with all of the information available about the process.

DWORD GetRunningProcesses( PROCESSENTRY32 *pProcess )
{

First thing is take a snapshot of the running processes.  CreateToolhelp32Snapshot() does this for us.  It is capable of doing more, but let's keep it simple to start with.  The first parameter is a set of flags that request what we want the function to do for us.  To get a snapshot of the running processes use TH32CS_SNAPPROCESS.  The second parameter is ignored when using TH32CS_SNAPPROCESS, so set it to zero.

 HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
 DWORD index = 0;

Do a little error handling, just in case.

 if(hSnapShot == (HANDLE)-1)
 {
  RETAILMSG( 1,
   (TEXT("GetRunningProcesses: Failed CreateToolhelp32Snapshot Error: %d\n"),
   GetLastError()));
  return 0;
 }

Now we are ready to fill the pProcess array with information about the running processes.  Start by clearing the first entry in the list and setting the size of the structure in the structure.  Then call Process32First to get the first process information.

 memset(pProcess,0,sizeof(PROCESSENTRY32));
 index = 0;
 pProcess->dwSize = sizeof(PROCESSENTRY32);
 if(Process32First(hSnapShot, pProcess))
 {

If there is a first process, and by now there better be, get the rest of the processes.  For this we will use Process32Next, which takes two parameters.  The first is the snapshot; the second is the result of the previous call to Process32Next or Process32First.  For that we should copy the result to the next entry in the array. Check along the way that we haven't overrun the array, which is another area that needs to be updated for Windows CE 6.0.

  while(TRUE)
  {
   index += 1;
   if( index < MAX_PROCESSES )
   {
    memcpy( pProcess + 1, pProcess, sizeof(PROCESSENTRY32));
    pProcess++;
    if(!Process32Next(hSnapShot, pProcess))
    {
     break;
    }
   }
   else
   {
    index = MAX_PROCESSES;
    break;
   }
  }
 }

Always good to close those handles.  Then return the number of processes that we found.

 CloseToolhelp32Snapshot (hSnapShot);
 return index ;
}

GetMaxProcessNameLength() loops through an array of PROCESSENTRY32 to find the maximum lenght of the process name.

DWORD GetMaxProcessNameLength( PROCESSENTRY32 lppe[MAX_PROCESSES], DWORD ProcessCount )
{
 DWORD index ;
 DWORD MaxLength = 0;
 DWORD CurrentLength;
 for( index = 0; index < ProcessCount; index++ )
 {
  CurrentLength = wcslen( lppe[ index ].szExeFile );
  if( MaxLength <  CurrentLength )
   MaxLength = CurrentLength;
 }
 return MaxLength;
 
}

So now we have a way to output the currently running processes.  I do need to update this for Windows CE 6.0.  I hope to get to that in the next few weeks.

Copyright © 2008 – Bruce Eitman
All Rights Reserved