Harddrive Usage?

Is it possible to get a usage statistic for the harddrive? I'm looking for somthing similar to the CPU usage statistic that can be found in the registry. This wouldn't have to be a perfect statistic, but just an approximate indicator of how hard the harddrive is working. For example 0% when it's idle. And 100% when it's spinning at it's full speed and conducting intensive access. If that's not possible, is there a way to just detect if harddrive activity is occuring at a certain point in time?
deck16Asked:
Who is Participating?
 
jdrescherConnect With a Mentor Commented:
> performance monitor, it will graph it for you and give numbers, but
its not something you can read in a program, just for humans to read and see what the holdup is

You can read the performance monitor data in a C++ program. Here is code to read the CPU Usage:

// CpuUsage.h: interface for the CCpuUsage class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_)
#define AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000




#define MAX_RAW_VALUES          20

const char szCounterName[] = "\\Processor(_Total)\\% Processor Time";

typedef struct _tag_PDHCounterStruct {
    HCOUNTER hCounter;      // Handle to the counter - given to use by PDH Library
    int nNextIndex;         // element to get the next raw value
    int nOldestIndex;       // element containing the oldes raw value
    int nRawCount;          // number of elements containing raw values
    PDH_RAW_COUNTER a_RawValue[MAX_RAW_VALUES]; // Ring buffer to contain raw values
} PDHCOUNTERSTRUCT, *PPDHCOUNTERSTRUCT;


class CCpuUsage  
{
public:
     CCpuUsage();
     virtual ~CCpuUsage();
     BOOL     Init();
     int GetUsage();

protected:

     PPDHCOUNTERSTRUCT               m_pCounterStruct;
     HQUERY                              m_hQuery;


};

#endif // !defined(AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_)


// CpuUsage.cpp: implementation of the CCpuUsage class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CpuUsage.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCpuUsage::CCpuUsage()
{
     m_hQuery = NULL;
     m_pCounterStruct = NULL;

}

CCpuUsage::~CCpuUsage()
{

     PdhCloseQuery(m_hQuery);
     delete m_pCounterStruct;
}


BOOL CCpuUsage::Init()
{
     if (ERROR_SUCCESS != PdhOpenQuery(NULL, 1, &m_hQuery))
          return FALSE;

    m_pCounterStruct = (PPDHCOUNTERSTRUCT) new PDHCOUNTERSTRUCT;

     PDH_STATUS pdh_status = PdhAddCounter(m_hQuery, szCounterName, (DWORD) m_pCounterStruct, &(m_pCounterStruct->hCounter));
    if (ERROR_SUCCESS != pdh_status)
     {
          return FALSE;
     }



     return TRUE;
}


int CCpuUsage::GetUsage()
{
    PDH_FMT_COUNTERVALUE pdhFormattedValue;

     PdhCollectQueryData(m_hQuery);

    if (ERROR_SUCCESS != PdhGetFormattedCounterValue(
                                    m_pCounterStruct->hCounter,
                                    PDH_FMT_LONG,
                                    NULL,
                                    &pdhFormattedValue ))


     {
          return 0;
     }

     return pdhFormattedValue.longValue;
}

remember to include pdh.h and link with pdh.lib.

To update this for harddrives change szCounterName[] = "\\PhysicalDisk(_Total)\\% Disk Time";


The _Total means all harddrives so if you want individual drives you must use their drive # ( can be found in disk administrator).

John

P.S. This code only works in NT 4.0, Win2k or XP. Because Win9X uses different perfomance monitor than nt4.0 +.

There is a wrapper class for Win9X that will allow you to read its performance counters at the following link:
http://www.naughter.com/dyndata.html

and
0
 
jonninCommented:
winnt and family have this in the performance monitor, it will graph it for you and give numbers, but its not something you can read in a program, just for humans to read and see what the holdup is...
0
 
deck16Author Commented:
umm, if the performance monitor can get the stats i should be able to do the same thing in my program.
0
Free Tool: Path Explorer

An intuitive utility to help find the CSS path to UI elements on a webpage. These paths are used frequently in a variety of front-end development and QA automation tasks.

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

 
deck16Author Commented:
does anybody have any ideas?
0
 
jonninCommented:
if you can't find a windows way, you can go low level. Trap the interrupt(s?) that writes to the hd and do something (take stats) when it trips.  The hd write is probably a bios interrupt, not sure, haven't looked at this since 386's were common...

windows may have a way you can use or it can cheat (the os knows when it is writing, even if it does not have a method to look at this that can be used)

0
 
1cand01tCommented:

probably u can do it thru StartTrace() function. fill out the EVENT_TRACE_PROPERTIES structure and enable the EVENT_TRACE_FLAG_DISK_IO flag.

see article "Starting an Event Tracing Session" on MSDN.

this may help u
good luck
0
 
jdrescherCommented:
> performance monitor, it will graph it for you and give numbers, but
its not something you can read in a program, just for humans to read and see what the holdup is

You can read the performance monitor data in a C++ program. Here is code to read the CPU Usage:

// CpuUsage.h: interface for the CCpuUsage class.
//
//////////////////////////////////////////////////////////////////////

#if !defined(AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_)
#define AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_

#if _MSC_VER > 1000
#pragma once
#endif // _MSC_VER > 1000




#define MAX_RAW_VALUES          20

const char szCounterName[] = "\\Processor(_Total)\\% Processor Time";

typedef struct _tag_PDHCounterStruct {
    HCOUNTER hCounter;      // Handle to the counter - given to use by PDH Library
    int nNextIndex;         // element to get the next raw value
    int nOldestIndex;       // element containing the oldes raw value
    int nRawCount;          // number of elements containing raw values
    PDH_RAW_COUNTER a_RawValue[MAX_RAW_VALUES]; // Ring buffer to contain raw values
} PDHCOUNTERSTRUCT, *PPDHCOUNTERSTRUCT;


class CCpuUsage  
{
public:
     CCpuUsage();
     virtual ~CCpuUsage();
     BOOL     Init();
     int GetUsage();

protected:

     PPDHCOUNTERSTRUCT               m_pCounterStruct;
     HQUERY                              m_hQuery;


};

#endif // !defined(AFX_CPUUSAGE_H__60CF4F03_9F01_41E8_A9FB_51F065D5F3C2__INCLUDED_)


// CpuUsage.cpp: implementation of the CCpuUsage class.
//
//////////////////////////////////////////////////////////////////////

#include "stdafx.h"
#include "CpuUsage.h"

#ifdef _DEBUG
#undef THIS_FILE
static char THIS_FILE[]=__FILE__;
#define new DEBUG_NEW
#endif

//////////////////////////////////////////////////////////////////////
// Construction/Destruction
//////////////////////////////////////////////////////////////////////

CCpuUsage::CCpuUsage()
{
     m_hQuery = NULL;
     m_pCounterStruct = NULL;

}

CCpuUsage::~CCpuUsage()
{

     PdhCloseQuery(m_hQuery);
     delete m_pCounterStruct;
}


BOOL CCpuUsage::Init()
{
     if (ERROR_SUCCESS != PdhOpenQuery(NULL, 1, &m_hQuery))
          return FALSE;

    m_pCounterStruct = (PPDHCOUNTERSTRUCT) new PDHCOUNTERSTRUCT;

     PDH_STATUS pdh_status = PdhAddCounter(m_hQuery, szCounterName, (DWORD) m_pCounterStruct, &(m_pCounterStruct->hCounter));
    if (ERROR_SUCCESS != pdh_status)
     {
          return FALSE;
     }



     return TRUE;
}


int CCpuUsage::GetUsage()
{
    PDH_FMT_COUNTERVALUE pdhFormattedValue;

     PdhCollectQueryData(m_hQuery);

    if (ERROR_SUCCESS != PdhGetFormattedCounterValue(
                                    m_pCounterStruct->hCounter,
                                    PDH_FMT_LONG,
                                    NULL,
                                    &pdhFormattedValue ))


     {
          return 0;
     }

     return pdhFormattedValue.longValue;
}

remember to include pdh.h and link with pdh.lib.

To update this for harddrives change szCounterName[] = "\\PhysicalDisk(_Total)\\% Disk Time";


The _Total means all harddrives so if you want individual drives you must use their drive # ( can be found in disk administrator).

John

P.S. This code only works in NT 4.0, Win2k or XP. Because Win9X uses different perfomance monitor than nt4.0 +.

There is a wrapper class for Win9X that will allow you to read its performance counters at the following link:
http://www.naughter.com/dyndata.html

and
0
 
deck16Author Commented:
oh dear, i seem to have forgotten about this question. thanks for the info. For 50 extra points could you tell me the string to use for szCounterName for all the different monitors (CPU, HDD, MEM, etc.)
0
 
jdrescherCommented:
>could you tell me the string to use for szCounterName for all the different monitors (CPU, HDD, MEM, etc.)

There are too many to list.
CPU
\\Processor(_Total)\\% Processor Time

HDD
\\PhysicalDisk(_Total)\\% Disk Time

MEM
Depends on what you want.

To get the counters for different objects run perfmon from the run command of the start menu and click add.

The format for the string is \\<object name>(<instance>)\\<counter> so in the cpu example:

object = Processor
instance = _Total
counter = % Processor Time

0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.