Listing Processes – Part 3: Using Tool Help Library

Tool Help Library makes it easy to enumerate and get info about processes, threads, modules, and heaps. Let’s use it to get a list of running processes.

Using Tool Help Library

First, take a snapshot by passing TH32CS_SNAPPROCESS flag to CreateToolhelp32Snapshot function. Next, pass the snapshot handle to Process32First, then to Process32Next to get running processes info in a list of PROCESSENTRY32 structures.

#include <Tlhelp32.h>

DWORD CDemoDlg::ToolHelp_EnumProcesses(CList<PROCESSENTRY32>& listProcInfo)
{
    DWORD dwRet = NO_ERROR;

    // take a snapshot of processes
    DWORD dwFlags = TH32CS_SNAPPROCESS;
    HANDLE hSnapshot = ::CreateToolhelp32Snapshot(dwFlags, 0);
    if(INVALID_HANDLE_VALUE == hSnapshot)
    {
        return ::GetLastError();
    }

    PROCESSENTRY32 processEntry = {0};
    processEntry.dwSize = sizeof(PROCESSENTRY32);
    // get info for each process in the snapshot
    if(::Process32First(hSnapshot, &processEntry))
    {
        do
        {   
            listProcInfo.AddTail(processEntry);
        }
        while(::Process32Next(hSnapshot, &processEntry));
    }
    else
    {
        dwRet = ::GetLastError();
    }
    ::CloseHandle(hSnapshot);
    return dwRet;
}

Next example fills a listview control with the following info of each process.

    • PID (process identifier);
    • process image name (the name of the executable file);
    • parent PID;
    • number of threads started by the process;
    • base priority of any threads created by this process.
void CDemoDlg::_FillProcessesList()
{
    // clear listview control
    m_listProcesses.DeleteAllItems();

    // get a list of PROCESSENTRY32 structures
    CList<PROCESSENTRY32> listProcInfo;
    VERIFY(NO_ERROR == ToolHelp_EnumProcesses(listProcInfo));

    // fill the listview control
    POSITION pos = listProcInfo.GetHeadPosition();
    int nIndex = 0;
    while(NULL != pos)
    {
        // get next process from the list
        const PROCESSENTRY32& procInfo = listProcInfo.GetNext(pos);

        // format info strings
        CString strPID, strImageName, strParentPID, strThreads, strPriority;
        strPID.Format(_T("%u"), procInfo.th32ProcessID);
        strImageName = procInfo.szExeFile;
        strParentPID.Format(_T("%u"), procInfo.th32ParentProcessID);
        strThreads.Format(_T("%u"), procInfo.cntThreads);
        strPriority.Format(_T("%d"), procInfo.pcPriClassBase);

        // set listview item text
        m_listProcesses.InsertItem(nIndex, strPID);
        m_listProcesses.SetItemText(nIndex, 1, strImageName);
        m_listProcesses.SetItemText(nIndex, 2, strParentPID);
        m_listProcesses.SetItemText(nIndex, 3, strThreads);
        m_listProcesses.SetItemText(nIndex++, 4, strPriority);
    }
}

Demo project

The demo project is a simple MFC dialog-based application that uses the above functions.
Download: Listing_Processes_Using_Tool_Help_Library.zip (1082 downloads)

Using Tool Help Library - Demo Application
Using Tool Help Library – Demo Application

Resources

See also

3 thoughts on “Listing Processes – Part 3: Using Tool Help Library”

  1. You can the same process info with commandline ps commands:
    :~$ ps -efL
    UID PID PPID LWP C NLWP STIME TTY TIME CMD
    root 1 0 1 0 1 00:33 ? 00:00:00 /sbin/init
    root 2 0 2 0 1 00:33 ? 00:00:00 [kthreadd]
    root 3 2 3 0 1 00:33 ? 00:00:00 [ksoftirqd/0]

    Where PPID is the Parent process of the PID and LWP gives the thread id of each thread. NLWP is the number of threads in the system for the underlying process. And, lot more process info with ps command options. Just see man ps and the web for examples of each.

    Reply
  2. And,
    ~$ ps -eo uname,pid,ppid,nlwp,pcpu,pmem,psr,start_time,tty,time,args

    USER PID PPID NLWP %CPU %MEM PSR START TT TIME COMMAND
    root 1 0 1 0.0 0.1 0 00:33 ? 00:00:00 /sbin/init
    root 2 0 1 0.0 0.0 0 00:33 ? 00:00:00 [kthreadd]
    root 3 2 1 0.0 0.0 0 00:33 ? 00:00:00 [ksoftirqd/0]

    Reply

Leave a Comment