A previous article shows how to list running processes from command line. Next, we’ll see how to get a list of processes in our own programs. Let’s start by using Process Status API (PSAPI).
Using PSAPI
Here is an example that calls EnumProcesses PSAPI function, then fills an array with the found process identifiers.
#include <Psapi.h>
#pragma comment(lib, "Psapi.lib")
// ...
DWORD CDemoDlg::PSAPI_EnumProcesses(CDWordArray& arrProcessIds,
DWORD dwMaxProcessCount)
{
DWORD dwRet = NO_ERROR;
arrProcessIds.RemoveAll();
DWORD *pProcessIds = new DWORD[dwMaxProcessCount];
DWORD cb = dwMaxProcessCount * sizeof(DWORD);
DWORD dwBytesReturned = 0;
// call PSAPI EnumProcesses
if(::EnumProcesses(pProcessIds, cb, &dwBytesReturned))
{
// fill the array with returned process IDs
const int nSize = dwBytesReturned / sizeof(DWORD);
arrProcessIds.SetSize(nSize);
for(int nIndex = 0; nIndex < nSize; nIndex++)
{
arrProcessIds[nIndex] = pProcessIds[nIndex];
}
}
else
{
dwRet = ::GetLastError();
}
delete []pProcessIds;
return dwRet;
}
Once having the process identifiers, we can call OpenProcess to get process handles, then use the handles in other functions which get info about processes. Next example fills a listview control with process identifiers, names and image file paths.
void CDemoDlg::_FillProcessesList()
{
// clear the listvie control
m_listProcesses.DeleteAllItems();
// get an array of process IDs
CDWordArray arrProcessIds;
VERIFY(NO_ERROR == PSAPI_EnumProcesses(arrProcessIds, 1024));
const int nSize = arrProcessIds.GetSize();
// fill the listview control
for(int nIndex = 0; nIndex < nSize; nIndex++)
{
DWORD dwProcessId = arrProcessIds[nIndex];
// get the process handle
HANDLE hProcess = ::OpenProcess(PROCESS_QUERY_INFORMATION,
FALSE, dwProcessId);
if(NULL != hProcess)
{
// insert new item in the list
const int nItemCount = m_listProcesses.GetItemCount();
m_listProcesses.InsertItem(nItemCount, NULL);
// format process ID
CString strProcessID;
strProcessID.Format(_T("%u"), dwProcessId);
// get executable file path (in device form)
CString strImageFileName;
::GetProcessImageFileName(hProcess,
CStrBuf(strImageFileName, MAX_PATH), MAX_PATH);
// get image name
CString strImageName = ::PathFindFileName(strImageFileName);
// set subitems text
m_listProcesses.SetItemText(nItemCount, 0, strProcessID);
m_listProcesses.SetItemText(nItemCount, 1, strImageName);
m_listProcesses.SetItemText(nItemCount, 2, strImageFileName);
// close the process handle
::CloseHandle(hProcess);
}
}
}
Demo project
Download: Listing_Processes_Using_PSAPI.zip (19 KB)
The demo project is a simple MFC dialog-based application that uses the above functions.

Resources
- MSDN: Process Status API
- MSDN: EnumProcesses function