[Last Call] Learn how to a build a cloud-first strategyRegister Now

x
?
Solved

Function to get CPU usage of specified process

Posted on 2006-03-26
23
Medium Priority
?
1,953 Views
Last Modified: 2008-01-09
Hello,

I really need a function that will take a string (or equivalent) of the name of a process, and return it's CPU usage at that moment in time.

I've tried coding something myself based on the huge number of stuff in the PAQ's, but am not getting anywhere...

My IDE is Dev-C++.

[BTW, I can guarantee that only 1 process with the specified name will be running at any given time].


Thanks very much !
0
Comment
Question by:InteractiveMind
  • 12
  • 10
23 Comments
 
LVL 86

Accepted Solution

by:
jkr earned 2000 total points
ID: 16294739
Check out http://www.codeproject.com/system/cpuusage.asp ("How to get CPU usage by performance counters (without PDH)") which IMO is the simplest way to do that and should work with Dev-C++. An advanced way would be PDH: http://www.codeproject.com/system/cpdh.asp ("CPdh v1.03 - NT Performance Info")
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16294804
Hey jkr.

I've shoved the source files provided in that link into a new project in Dev-C++, and have tried to compile - but am getting a load of errors...

Just a few of which area:

atlbase.h: No such file or directory.
comdef.h: No such file or directory.
.
.
and a few syntax errors..


Any ideas ?

Thanks
0
 
LVL 86

Expert Comment

by:jkr
ID: 16294838
Hm, 'atlbase.h' is used only in CpuUsage.cpp - and only for 'CRegKey' in

BOOL CCpuUsage::EnablePerformaceCounters(BOOL bEnable)
{
      if (GetPlatform() != WIN2K_XP)
            return TRUE;

      CRegKey regKey;
      if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfOS\\Performance") != ERROR_SUCCESS)
            return FALSE;

      regKey.SetValue(!bEnable, "Disable Performance Counters");
      regKey.Close();

      if (regKey.Open(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfProc\\Performance") != ERROR_SUCCESS)
            return FALSE;

      regKey.SetValue(!bEnable, "Disable Performance Counters");
      regKey.Close();

      return TRUE;
}

If you change that to regular Win32 Registry APIs, you can just delete the lines

#include "stdafx.h"
#include <atlbase.h>      // for CRegKey use

'comdef.h' however should be availyble with Dev-C++
0
What does it mean to be "Always On"?

Is your cloud always on? With an Always On cloud you won't have to worry about downtime for maintenance or software application code updates, ensuring that your bottom line isn't affected.

 
LVL 25

Author Comment

by:InteractiveMind
ID: 16294867
Perhaps I need to add a library or something ?  :-\
0
 
LVL 86

Expert Comment

by:jkr
ID: 16294917
No, 'comdef.h' is for the basic COM support classes. But you can eliminate this issue by changing

            // Look for instance pInstanceName
            _bstr_t bstrInstance;
            _bstr_t bstrInputInstance = pInstanceName;
            for( int k=0; k < pPerfObj->NumInstances; k++ )
            {
                bstrInstance = (wchar_t *)((PBYTE)pPerfInst + pPerfInst->NameOffset);
                if (!stricmp((LPCTSTR)bstrInstance, (LPCTSTR)bstrInputInstance))
                {
                    pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst + pPerfInst->ByteLength);
                    break;
                }
               
                // Get the next instance.

                pPerfInst = NextInstance( pPerfInst );
            }

to

            // Look for instance pInstanceName
            wchar_t* bstrInstance;
            wchar_t* bstrInputInstance = new wchar_t[strlen(pInstanceName) + 1];
                  mbstowcs(bstrInputInstance,pInstanceName,strlen(pInstanceName) + 1);
            for( int k=0; k < pPerfObj->NumInstances; k++ )
            {
                bstrInstance = (wchar_t *)((PBYTE)pPerfInst + pPerfInst->NameOffset);
                if (!_wcsicmp(bstrInstance, bstrInputInstance))
                {
                    pCounterBlock = (PPERF_COUNTER_BLOCK) ((LPBYTE) pPerfInst + pPerfInst->ByteLength);
                    break;
                }
               
                // Get the next instance.

                pPerfInst = NextInstance( pPerfInst );
            }
            delete [] bstrInputInstance;

in 'PerfCounters.h' and substitute 'comdef.h' by 'string.h'
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16294937
Ah k; that seems to have gotten rid of the comdef.h error message..

As for "change that to regular Win32 Registry APIs" ... how would I do this?

Ta
0
 
LVL 86

Expert Comment

by:jkr
ID: 16294996
Just like

BOOL CCpuUsage::EnablePerformaceCounters(BOOL bEnable)
{
     if (GetPlatform() != WIN2K_XP)
          return TRUE;

     DWORD dw = bEnable ? 1 : 0;
     HKEY regKey;
     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfOS\\Performance",0, KEY_SET_VALUE, &regKey))
          return FALSE;

     RegSetValueEx(rekKey, "Disable Performance Counters", 0, REG_DWORD, (LPVOID) &dw, sizeof(DWORD));
     RegCloseKey(regKey);

     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfProc\\Performance",0, KEY_SET_VALUE, &regKey))
          return FALSE;

     RegSetValueEx(rekKey, "Disable Performance Counters", 0, REG_DWORD, (LPVOID) &dw, sizeof(DWORD));
     RegCloseKey(regKey);

     return TRUE;
}
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295012
Yup, that's sorted that bit.... now just another 19 error messages :(

They mostly seem to be syntax errors.. :\


Here's my Compile Log:


Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\rob\Desktop\Makefile.win"
Executing  make...
make.exe -f "C:\Documents and Settings\rob\Desktop\Makefile.win" all
g++.exe -c CpuUsage_src/CpuUsage.cpp -o CpuUsage_src/CpuUsage.o -I"C:/Program Files/Dev-Cpp/include/c++/3.3.1"  -I"C:/Program Files/Dev-Cpp/include/c++/3.3.1/mingw32"  -I"C:/Program Files/Dev-Cpp/include/c++/3.3.1/backward"  -I"C:/Program Files/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include"  -I"C:/Program Files/Dev-Cpp/include"  -I"C:/Program Files/Java/jdk1.5.0_01/include"  -I"C:/Program Files/Java/jdk1.5.0_01/include/win32"  

CpuUsage_src/CpuUsage.cpp:47: error: syntax error before numeric constant
CpuUsage_src/CpuUsage.cpp:48: error: ISO C++ forbids declaration of `PLATFORM'
   with no type
CpuUsage_src/CpuUsage.cpp:50: error: syntax error before `)' token
CpuUsage_src/CpuUsage.cpp:53: error: syntax error before `.' token

CpuUsage_src/CpuUsage.cpp: In member function `BOOL
   CCpuUsage::EnablePerformaceCounters(int)':
CpuUsage_src/CpuUsage.cpp:82: error: `GetPlatform' undeclared (first use this
   function)
CpuUsage_src/CpuUsage.cpp:82: error: (Each undeclared identifier is reported
   only once for each function it appears in.)
CpuUsage_src/CpuUsage.cpp:82: error: `WIN2K_XP' undeclared (first use this
   function)

CpuUsage_src/CpuUsage.cpp:90: error: invalid conversion from `void*' to `const
   BYTE*'

CpuUsage_src/CpuUsage.cpp:96: error: invalid conversion from `void*' to `const
   BYTE*'

CpuUsage_src/CpuUsage.cpp: In member function `int CCpuUsage::GetCpuUsage()':
CpuUsage_src/CpuUsage.cpp:111: error: ISO C++ forbids declaration of `PLATFORM'
   with no type
CpuUsage_src/CpuUsage.cpp:111: error: syntax error before `=' token

CpuUsage_src/CpuUsage.cpp:131: error: `Platform' undeclared (first use this
   function)

CpuUsage_src/CpuUsage.cpp: In member function `int CCpuUsage::GetCpuUsage(const
   TCHAR*)':

CpuUsage_src/CpuUsage.cpp:179: error: ISO C++ forbids declaration of `PLATFORM'
   with no type
CpuUsage_src/CpuUsage.cpp:179: error: syntax error before `=' token

CpuUsage_src/CpuUsage.cpp: In member function `int CCpuUsage::GetCpuUsage(long
   unsigned int)':
CpuUsage_src/CpuUsage.cpp:226: error: ISO C++ forbids declaration of `PLATFORM'
   with no type
CpuUsage_src/CpuUsage.cpp:226: error: syntax error before `=' token

CpuUsage_src/PerfCounters.h: In member function `void
   CPerfCounters<T>::CBuffer::Reset() [with T = LONGLONG]':
CpuUsage_src/PerfCounters.h:140:   instantiated from `void CPerfCounters<T>::QueryPerformanceData(PERF_DATA_BLOCK**, long unsigned int, long unsigned int) [with T = LONGLONG]'
CpuUsage_src/PerfCounters.h:22:   instantiated from `T CPerfCounters<T>::GetCounterValue(PERF_DATA_BLOCK**, long unsigned int, long unsigned int, const TCHAR*) [with T = LONGLONG]'
CpuUsage_src/CpuUsage.cpp:151:   instantiated from here
CpuUsage_src/PerfCounters.h:95: warning: passing NULL used for non-pointer
   argument passing 2 of `void* memset(void*, int, unsigned int)'
CpuUsage_src/PerfCounters.h:95: warning: argument to non-pointer type `int'
   from NULL

make.exe: *** [CpuUsage_src/CpuUsage.o] Error 1

Execution terminated



Is there really no easier way of doing this? :-\
0
 
LVL 86

Expert Comment

by:jkr
ID: 16295051
Nope. But, the error mainly boils down to

typedef enum
{
      WINNT,      WIN2K_XP, WIN9X, UNKNOWN
}PLATFORM;

which is actually valid. You could try

enum PLATFORM
{
      WINNT,      WIN2K_XP, WIN9X, UNKNOWN
};
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295071
Hmm; making that change is now resulting in 23 errors  :-\
0
 
LVL 86

Expert Comment

by:jkr
ID: 16295121
What about

enum _PLATFORM
{
     WINNT,     WIN2K_XP, WIN9X, UNKNOWN
} PLATFORM;

?

If this also goes wrong, make that

typedef int PLATFORM;
#define WINNT 1
#define WIN2K_XP 2
#define WIN9X 3
#define UNKNOWN -1
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295134
Okay, the last suggestion sorts most of that....

Just 5 errors left  :)


Compiler: Default compiler
Building Makefile: "C:\Documents and Settings\rob\Desktop\Makefile.win"
Executing  make...
make.exe -f "C:\Documents and Settings\rob\Desktop\Makefile.win" all
g++.exe -c CpuUsage_src/CpuUsage.cpp -o CpuUsage_src/CpuUsage.o -I"C:/Program Files/Dev-Cpp/include/c++/3.3.1"  -I"C:/Program Files/Dev-Cpp/include/c++/3.3.1/mingw32"  -I"C:/Program Files/Dev-Cpp/include/c++/3.3.1/backward"  -I"C:/Program Files/Dev-Cpp/lib/gcc-lib/mingw32/3.3.1/include"  -I"C:/Program Files/Dev-Cpp/include"  -I"C:/Program Files/Java/jdk1.5.0_01/include"  -I"C:/Program Files/Java/jdk1.5.0_01/include/win32"  

CpuUsage_src/CpuUsage.cpp: In member function `BOOL
   CCpuUsage::EnablePerformaceCounters(int)':
CpuUsage_src/CpuUsage.cpp:90: error: invalid conversion from `void*' to `const
   BYTE*'
CpuUsage_src/CpuUsage.cpp:96: error: invalid conversion from `void*' to `const
   BYTE*'

CpuUsage_src/PerfCounters.h: In member function `void
   CPerfCounters<T>::CBuffer::Reset() [with T = LONGLONG]':
CpuUsage_src/PerfCounters.h:140:   instantiated from `void CPerfCounters<T>::QueryPerformanceData(PERF_DATA_BLOCK**, long unsigned int, long unsigned int) [with T = LONGLONG]'
CpuUsage_src/PerfCounters.h:22:   instantiated from `T CPerfCounters<T>::GetCounterValue(PERF_DATA_BLOCK**, long unsigned int, long unsigned int, const TCHAR*) [with T = LONGLONG]'
CpuUsage_src/CpuUsage.cpp:151:   instantiated from here
CpuUsage_src/PerfCounters.h:95: warning: passing NULL used for non-pointer
   argument passing 2 of `void* memset(void*, int, unsigned int)'
CpuUsage_src/PerfCounters.h:95: warning: argument to non-pointer type `int'
   from NULL

make.exe: *** [CpuUsage_src/CpuUsage.o] Error 1

Execution terminated


:D
0
 
LVL 30

Expert Comment

by:Axter
ID: 16295157
I use boost::progress_timer.
Check out following link:
http://athene.berlios.de/classboost_1_1progress__timer.html
0
 
LVL 86

Expert Comment

by:jkr
ID: 16295163
Ah, getting closer - that should be

BOOL CCpuUsage::EnablePerformaceCounters(BOOL bEnable)
{
     if (GetPlatform() != WIN2K_XP)
          return TRUE;

     DWORD dw = bEnable ? 1 : 0;
     HKEY regKey;
     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfOS\\Performance",0, KEY_SET_VALUE, &regKey))
          return FALSE;

     RegSetValueEx(rekKey, "Disable Performance Counters", 0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
     RegCloseKey(regKey);

     if (ERROR_SUCCESS != RegOpenKeyEx(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Services\\PerfProc\\Performance",0, KEY_SET_VALUE, &regKey))
          return FALSE;

     RegSetValueEx(rekKey, "Disable Performance Counters", 0, REG_DWORD, (LPBYTE) &dw, sizeof(DWORD));
     RegCloseKey(regKey);

     return TRUE;
}

The rest are only warnings.
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295184
Okay, one last thing:

CpuUsage_src/PerfCounters.h: In member function `void
   CPerfCounters<T>::CBuffer::Reset() [with T = LONGLONG]':
CpuUsage_src/PerfCounters.h:140:   instantiated from `void CPerfCounters<T>::QueryPerformanceData(PERF_DATA_BLOCK**, long unsigned int, long unsigned int) [with T = LONGLONG]'
CpuUsage_src/PerfCounters.h:22:   instantiated from `T CPerfCounters<T>::GetCounterValue(PERF_DATA_BLOCK**, long unsigned int, long unsigned int, const TCHAR*) [with T = LONGLONG]'
CpuUsage_src/CpuUsage.cpp:151:   instantiated from here

Apparently it doesn't like this line in PerfCounters.h:

Buffer.Reset();

?
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295202
Oh, that's the warning thing....

nvm :)

Is there a way to disable warnings in Dev-C++ ? :)
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295240
Okay, that's all compiling fine now, and has produced an exe :)

However ...

When I run the program, the "SystemWide Cpu Usage" is stuck at 100%, and the other two measurements are both at 0%...

(But, if I run the pre-compiled demo from that site, it's giving correct output..)
0
 
LVL 86

Expert Comment

by:jkr
ID: 16295268
Can you check the registry whether the flags have been set correctly?
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295296
If you mean:

HKLM\SYSTEM\CurrentControlSet\Services\PerfOS\Performance\Disable Performance Counters
and
HKLM\SYSTEM\CurrentControlSet\Services\PerfProc\Performance\Disable Performance Counters

Then yes, they exist (both with value 0x00000001) ...
0
 
LVL 86

Expert Comment

by:jkr
ID: 16295383
Ah, that's the problem - change


     DWORD dw = bEnable ? 1 : 0;

to


     DWORD dw = bEnable ? 0 : 1;
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16295400
..And it works !!!

Magic.

Thanks very much for going through this with me, jkr.. I tried to get this thing working many months ago - with no luck.
So, I'm really happy now :D

Thanks !!
0
 
LVL 86

Expert Comment

by:jkr
ID: 16295435
You're most welcome ;o)
0
 
LVL 25

Author Comment

by:InteractiveMind
ID: 16301765
By the way; it would seem that the GetCpuUsage() returns 0 the first time it's called [everytime].. This is quite obvious when looking at the code... but is there a way to retrieve the CPU usage with only a single call to that function? (Because I need to shove it into a DLL, and calling that function twice within the DLL doesn't seem to be working...)

I think that I've had more than my share of help in this thread [for just 500 points] -- so have posted a new thread regarding this problem. :)

http://www.experts-exchange.com/Programming/Programming_Languages/Cplusplus/Q_21790438.html

Cheers.
0

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Unlike C#, C++ doesn't have native support for sealing classes (so they cannot be sub-classed). At the cost of a virtual base class pointer it is possible to implement a pseudo sealing mechanism The trick is to virtually inherit from a base class…
IntroductionThis article is the second in a three part article series on the Visual Studio 2008 Debugger.  It provides tips in setting and using breakpoints. If not familiar with this debugger, you can find a basic introduction in the EE article loc…
The viewer will learn how to use the return statement in functions in C++. The video will also teach the user how to pass data to a function and have the function return data back for further processing.
The viewer will be introduced to the technique of using vectors in C++. The video will cover how to define a vector, store values in the vector and retrieve data from the values stored in the vector.
Suggested Courses

829 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question