Click here to Skip to main content
15,891,777 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
I am using WMI interface to get various counter values like memory/ disk/IO utilisations. I also got total percentage CPU utilisation using WIN32_Process class.

But I need percentage CPU utilisation per process. Please help me out with VC++ code to do this.

I am using VS2010 as IDE
Posted

1 solution

You can use the GetProcessTimes function to get the times per process:
A quick and dirty example:
[Edit] improved solution.
C++
#pragma once
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <tchar.h>
#include <Psapi.h>
#include <CommCtrl.h>
#include <malloc.h>

#pragma comment (lib,"Psapi.lib")
#pragma comment (lib,"user32.lib")
#pragma comment (lib,"comctl32.lib")

#pragma comment(linker,"\"/manifestdependency:type='win32' \
name='Microsoft.Windows.Common-Controls' version='6.0.0.0' \
processorArchitecture='*' publicKeyToken='6595b64144ccf1df' language='*'\"")

template <class TI>
class tArray
{
public:
  tArray(){ count=0array=0; }
  ~tArray(){ if(array) free(array); }
  void    Resize(const size_t n){ array=(TI*)(array?realloc(array,sizeof(TI)*n):malloc(sizeof(TI)*n)); count=n; }
public:
  size_t  count;
  TI*      array;
};

static double __todouble(const FILETIME& ft)
{
  return (4294967296.0 * (double)ft.dwHighDateTime) + (double)ft.dwLowDateTime;
}
static int __isnull(const FILETIME& ft)
{
  return (ft.dwHighDateTime|ft.dwLowDateTime)?0:1;
}

enum{ IDC_LIST=101, };

void OnTimer(HWND hlist)
{
  if(!IsWindow(hlist)) return;

  tArray<unsigned long>  array;
  unsigned long          count;
  unsigned long          ix,len;
  HANDLE                hproc;
  TCHAR                  mod[0x4000];
  LVITEM                lvi;
  int                    nitems;
  const double          nanoseconds100 = 100.0/1e9;
  
  nitems = ListView_GetItemCount(hlist);
  lvi.iItem = 0;

  // get the process ids of all running processes
  // see: http://msdn.microsoft.com/en-us/library/ms682629(VS.85).aspx
  for
  (
    count=0,array.Resize(256);
    EnumProcesses(array.array,sizeof(unsigned long)*array.count,&count);
    array.Resize(array.count<<1)
  )
  {
    count /= sizeof(unsigned long);
    if(array.count>count)
      break;
  }

  for(ix=0;ix<count;ix++)
  {
    // open process so you can read process informations
    // see: http://msdn.microsoft.com/en-us/library/ms684320(VS.85).aspx
    hproc = OpenProcess(PROCESS_QUERY_INFORMATION|PROCESS_VM_READ,1,array.array[ix]);
    if(hproc && (INVALID_HANDLE_VALUE!=hproc))
    {
      FILETIME  ftc,fte,ftk,ftu,ftn;
      // get the current time for the process they arent stopped
      GetSystemTimeAsFileTime(&ftn);
      // get the process times for the process
      // see: http://msdn.microsoft.com/en-us/library/ms683223(VS.85).aspx
      if(GetProcessTimes(hproc,&ftc,&fte,&ftk,&ftu))
      {
        // process start time
        double  t0 = __todouble(ftc);
        // process stop time or current time
        double  t1 = __isnull(fte)?__todouble(ftn):__todouble(fte);
        // user mode time
        double  uu = __todouble(ftu);
        // kernel time
        double  kk = __todouble(ftk);

        len = sizeof(mod)/sizeof(mod[0]);
        // get the process name (executable)
        // see: http://msdn.microsoft.com/en-us/library/ms684919(VS.85).aspx
        if(!QueryFullProcessImageName(hproc,0,mod,&len)) len = 0;
        mod[len] = 0;
        
        lvi.mask = LVIF_TEXT;
        lvi.pszText = mod;
        lvi.iSubItem = 0;

        if(lvi.iItem<nitems)
          ListView_SetItem(hlist,&lvi);
        else
          ListView_InsertItem(hlist,&lvi);

        // user-time
        ++lvi.iSubItem;
        // user time column value
        // remember filetime is in 100 nanoseconds resolution
        _stprintf_s(mod,sizeof(mod)/sizeof(mod[0]),__TEXT("%.3lf"),uu*nanoseconds100);
        lvi.mask = LVIF_TEXT;
        lvi.pszText = mod;
        ListView_SetItem(hlist,&lvi);

        // total-time
        ++lvi.iSubItem;
        // total time column value
        _stprintf_s(mod,sizeof(mod)/sizeof(mod[0]),__TEXT("%.3lf"),(t1-t0)*nanoseconds100);
        lvi.mask = LVIF_TEXT;
        lvi.pszText = mod;
        ListView_SetItem(hlist,&lvi);

        // %
        // percentage (utilisation) for user time
        // full (utilisation) is == 100.0*(uu+kk)/(t1-t0) thats the value you want!
        ++lvi.iSubItem;
        _stprintf_s(mod,sizeof(mod)/sizeof(mod[0]),__TEXT("%.2lf"),100.0*uu/(t1-t0));
        lvi.mask = LVIF_TEXT;
        lvi.pszText = mod;
        ListView_SetItem(hlist,&lvi);

        ++lvi.iItem;
      }

      CloseHandle(hproc);
    }
    
  }
  for(;lvi.iItem<nitems;nitems--) ListView_DeleteItem(hlist,lvi.iItem);

}

void OnInit(HWND hDlg)
{
  HWND  hlist;
  SetTimer(hDlg,100,1000,0);
  hlist = GetDlgItem(hDlg,IDC_LIST);

  if(hlist)
  {
    int        icol = 0;
    LVCOLUMN  lvc = {LVCF_TEXT|LVCF_WIDTH,0};
    RECT      rc; GetClientRect(hlist,&rc);
    int        width = rc.right-rc.left-GetSystemMetrics(SM_CXVSCROLL);

    lvc.cx = MulDiv(width,60,100);
    lvc.pszText = __TEXT("module");
    if(-1!=ListView_InsertColumn(hlist,icol,&lvc)) ++icol;
    lvc.fmt = LVCFMT_RIGHT;lvc.mask |= LVCF_FMT;
    lvc.cx = MulDiv(width,15,100);
    lvc.pszText = __TEXT("user-time");
    if(-1!=ListView_InsertColumn(hlist,icol,&lvc)) ++icol;
    lvc.cx = MulDiv(width,15,100);
    lvc.pszText = __TEXT("total-time");
    if(-1!=ListView_InsertColumn(hlist,icol,&lvc)) ++icol;
    lvc.cx = MulDiv(width,10,100);
    lvc.pszText = __TEXT("%");
    if(-1!=ListView_InsertColumn(hlist,icol,&lvc)) ++icol;
    
    ListView_SetExtendedListViewStyle(hlist,LVS_EX_FULLROWSELECT|LVS_EX_DOUBLEBUFFER );
    OnTimer(hlist);
  }
}

static int FAR PASCAL __dlgproc(HWND h,unsigned int m,WPARAM w,LPARAM l)
{
  switch(m)
  {
    case WM_INITDIALOG: OnInit(h); break;
    case WM_TIMER: OnTimer(GetDlgItem(h,IDC_LIST)); break;
    case WM_CLOSE: EndDialog(h,0); break;
  }
  return 0;
}

int FAR PASCAL _tWinMain(HINSTANCE h,HINSTANCE p,LPTSTR c,int sw)
{
  struct
  {
    DLGTEMPLATE      t;
    unsigned short  menu;
    unsigned short  wclass;
    unsigned short  title[13];
    unsigned short  font_size;
    unsigned short  font_face[8];

    unsigned char    dword_padding[2];

    struct
    {
      DLGITEMTEMPLATE  t;
      unsigned short  wclass[sizeof(WC_LISTVIEW)/sizeof(TCHAR)];
      unsigned short  title[1];
      unsigned short  data;

    }                list;

    enum { WS=WS_CHILD|WS_VISIBLE|WS_TABSTOP, };

  } dlgt =
  {
    {WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX|DS_CENTER|DS_SETFONT,0,1,0,0,400,300},0,0,L"Process view",
    10,L"Verdana",{0},
    // list
    {{dlgt.WS|WS_BORDER|LVS_REPORT|LVS_SINGLESEL,0,4,4,390,280,IDC_LIST},WC_LISTVIEW,L"",0},
  };

  InitCommonControls();
  DialogBoxIndirectParam(h,(DLGTEMPLATE*)&dlgt,(HWND)0,__dlgproc,0);

  return 0;
}

Good luck.
 
Share this answer
 
v2
Comments
Jayanth G H 21-Sep-11 1:56am    
Hi thanks for your time to reply for my post. Your code gives processor times but I need Processor utilisation % per process..
mbue 21-Sep-11 2:04am    
The times gives you the usage in user and kernel times for each process. In relation to the running time you get the utilisation. Or did i misunderstood - define your imagine of utilisation!
Regards.
Jayanth G H 21-Sep-11 2:28am    
User mode time+ kernel mode time=Total Processor time... Can you please tell me how you can get % CPU utilisation load per process using processing time.. If you open a task manager you will find a column CPU. I want this programmatically per process. I hope I am clear to your question.
mbue 21-Sep-11 12:17pm    
Ive updated the solution above and marked the relevant code positions by comments.
Regards.
Jayanth G H 26-Sep-11 10:32am    
Hi mbue thanks for your reply.:)But I am getting the Error "error C2440: 'initializing' : cannot convert from 'const wchar_t [13]' to 'unsigned short'" in the line {WS_OVERLAPPED|WS_SYSMENU|WS_MINIMIZEBOX|DS_CENTER|DS_SETFONT,0,1,0,0,400,300},0,0,L"Process view",
10,L"Verdana",{0}....Another error is "error C2078: too many initializers" in line {dlgt.WS|WS_BORDER|LVS_REPORT|LVS_SINGLESEL,0,4,4,390,280,IDC_LIST},WC_LISTVIEW,L"",0}

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900