CPU占用率
2008-11-08 08:49 ubunoon 阅读(3035) 评论(3) 编辑 收藏 举报
下面是头文件
/************************************************************************/
/*
* 作者:cpp
* 日期:2008-09-05
* 内容:提供了一个CSystemInformation类,该类可以获取CPU厂家,
* CPU频率,CPU个数,当前使用的CPU,系统运行时占用的
* CPU比率,系统运行的Idle时间,User时间以及Kernel时间
* 获取某个进程的句柄个数,获取随机数(比编译器自带更灵活),
* 以及将长整数(long long )转换为浮点数,宽字节与窄字节之间的互换
*
* 注意:有几个函数仅可以用在windows xp系统上,在其他系统上将失效或不起作用
* 因此,调用时需要注意,另外,如果转入到其他编译器_WIN32_WINNT用来
* 指示需要windows xp系统
*/
/************************************************************************/
#pragma once
#include<sstream>
#include <cassert>
#ifndef _WINBASE_
#include <WinBase.h>
#endif // _WINBASE_H
//#define _WIN32_WINNT // 该值已经在stdafx.h中被声明过,只能够用在winxp系统上
typedef struct _SYSTEM_BASIC_INFORMATION {
BYTE Reserved1[24];
PVOID Reserved2[4];
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION; // 结构等同于SYSTEM_INFO
typedef struct
{
long long IdleTime;
DWORD dwReversed[76];
} SYSTEM_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
BYTE Reserved1[52];
PVOID Reserved2[3];
HANDLE UniqueProcessId;
PVOID Reserved3;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION;
typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION; // 等同于GetSystemTimes获取到的三个数据
class CSystemInformation
{
public:
// 定义基础数据类型
typedef std::basic_string<TCHAR> string;
typedef std::basic_stringstream<TCHAR> stringstream;
typedef std::basic_string<BYTE> byteString;
public:
enum SYSTEM_INFORMATION
{
SystemBasicInformation = 0,
SystemPerformanceInformation = 2,
SystemTimeInformation = 3,
};
protected:
typedef DWORD (WINAPI* NTQUERYSYSTEMINFOMATION) (
SYSTEM_INFORMATION SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength );
public:
CSystemInformation(void);
public:
~CSystemInformation(void);
public:
// 获取基础信息系统,并返回处理
const LPSYSTEM_INFO GetSystemInfo(void);
protected:
// 处理错误消息
void ProcessErrorMessage(TCHAR* ErrorText);
public:
// 产生给定长度的随机数,由windows系统产生,比C编译器产生的更加随机
byteString GenRandom(int len);
public:
// 返回转换后的wchar_t指针,并返回长度
wchar_t* ToChar(const char* str, int* len);
public:
// 返回转换后的char指针,并返回长度
char* ToChar(const wchar_t* str, int* len);
public:
// 获取本地机器的CPU硬件信息
string GetCPUCompany(void);
public:
// 获取CPU个数
int GetCPUNumbers(void);
public:
// 获取当前CPU编号-即当前使用的是哪个CPU
int GetCurrentCPU(void);
public:
// 获取某个打开进程的句柄个数
long GetProcessHandleCount(HANDLE hProcess);
public:
// 获取系统空闲时间
LPFILETIME GetIdleTime(void);
public:
// 获取系统核心运行时间
LPFILETIME GetKernelTime(void);
// 获取用户运行时间
LPFILETIME GetUserTime(void);
public:
// 获取系统(空闲,核心以及用户)运行时间
void GetSystemTimes(LPFILETIME IdleTime, LPFILETIME KernelTime, LPFILETIME UserTime, bool ImmediateRet=false);
public:
// 获取CPU占用率
double GetCPURate(void);
public:
// 将64位的长整数转换为64位的实数
double LongInt2Double(LARGE_INTEGER want);
public:
double LongInt2Double(long long want)
{
LARGE_INTEGER _want;
memcpy( &_want, &want, sizeof(LARGE_INTEGER) );
return LongInt2Double( _want );
}
double LongInt2Double(FILETIME want)
{
LARGE_INTEGER _want;
memcpy( &_want, &want, sizeof(LARGE_INTEGER) );
return LongInt2Double( _want);
}
public:
// 获取CPU的频率,高字节部分为主频,低字节部分为次频,以GHz为单位
int GetCPUFrenquence(void);
public:
// 获取当前使用的CPU编号
int GetCurrentUseCPU(void);
public:
// 获取注册表所能够达到的最大尺寸,以字节为单位
long GetMaxRegisterSize(void);
public:
// 获取当前注册表的尺寸,以字节为单位
long GetCurrRegisterSize(void);
private:
long long m_IdleTime;
long long m_KernelTime;
long long m_UserTime;
// 用来表示是否已经获取了系统的信息,true为已经获取,false为没有获取
bool m_bHasSystemInfo;
wchar_t *m_pWChar;
char *m_pchar;
private:
// 系统信息
SYSTEM_INFO m_system_info;
private:
// NTDLL.DLL 句柄
HMODULE m_hNtDll;
// NtQuerySystemInformation 函数地址
NTQUERYSYSTEMINFOMATION NtQuerySystemInformation;
};
下面是实现文件:/*
* 作者:cpp
* 日期:2008-09-05
* 内容:提供了一个CSystemInformation类,该类可以获取CPU厂家,
* CPU频率,CPU个数,当前使用的CPU,系统运行时占用的
* CPU比率,系统运行的Idle时间,User时间以及Kernel时间
* 获取某个进程的句柄个数,获取随机数(比编译器自带更灵活),
* 以及将长整数(long long )转换为浮点数,宽字节与窄字节之间的互换
*
* 注意:有几个函数仅可以用在windows xp系统上,在其他系统上将失效或不起作用
* 因此,调用时需要注意,另外,如果转入到其他编译器_WIN32_WINNT用来
* 指示需要windows xp系统
*/
/************************************************************************/
#pragma once
#include<sstream>
#include <cassert>
#ifndef _WINBASE_
#include <WinBase.h>
#endif // _WINBASE_H
//#define _WIN32_WINNT // 该值已经在stdafx.h中被声明过,只能够用在winxp系统上
typedef struct _SYSTEM_BASIC_INFORMATION {
BYTE Reserved1[24];
PVOID Reserved2[4];
CCHAR NumberOfProcessors;
} SYSTEM_BASIC_INFORMATION; // 结构等同于SYSTEM_INFO
typedef struct
{
long long IdleTime;
DWORD dwReversed[76];
} SYSTEM_PERFORMANCE_INFORMATION;
typedef struct _SYSTEM_PROCESS_INFORMATION {
ULONG NextEntryOffset;
BYTE Reserved1[52];
PVOID Reserved2[3];
HANDLE UniqueProcessId;
PVOID Reserved3;
ULONG HandleCount;
BYTE Reserved4[4];
PVOID Reserved5[11];
SIZE_T PeakPagefileUsage;
SIZE_T PrivatePageCount;
LARGE_INTEGER Reserved6[6];
} SYSTEM_PROCESS_INFORMATION;
typedef struct
{
LARGE_INTEGER liKeBootTime;
LARGE_INTEGER liKeSystemTime;
LARGE_INTEGER liExpTimeZoneBias;
ULONG uCurrentTimeZoneId;
DWORD dwReserved;
} SYSTEM_TIME_INFORMATION; // 等同于GetSystemTimes获取到的三个数据
class CSystemInformation
{
public:
// 定义基础数据类型
typedef std::basic_string<TCHAR> string;
typedef std::basic_stringstream<TCHAR> stringstream;
typedef std::basic_string<BYTE> byteString;
public:
enum SYSTEM_INFORMATION
{
SystemBasicInformation = 0,
SystemPerformanceInformation = 2,
SystemTimeInformation = 3,
};
protected:
typedef DWORD (WINAPI* NTQUERYSYSTEMINFOMATION) (
SYSTEM_INFORMATION SystemInformationClass,
PVOID SystemInformation,
ULONG SystemInformationLength,
PULONG ReturnLength );
public:
CSystemInformation(void);
public:
~CSystemInformation(void);
public:
// 获取基础信息系统,并返回处理
const LPSYSTEM_INFO GetSystemInfo(void);
protected:
// 处理错误消息
void ProcessErrorMessage(TCHAR* ErrorText);
public:
// 产生给定长度的随机数,由windows系统产生,比C编译器产生的更加随机
byteString GenRandom(int len);
public:
// 返回转换后的wchar_t指针,并返回长度
wchar_t* ToChar(const char* str, int* len);
public:
// 返回转换后的char指针,并返回长度
char* ToChar(const wchar_t* str, int* len);
public:
// 获取本地机器的CPU硬件信息
string GetCPUCompany(void);
public:
// 获取CPU个数
int GetCPUNumbers(void);
public:
// 获取当前CPU编号-即当前使用的是哪个CPU
int GetCurrentCPU(void);
public:
// 获取某个打开进程的句柄个数
long GetProcessHandleCount(HANDLE hProcess);
public:
// 获取系统空闲时间
LPFILETIME GetIdleTime(void);
public:
// 获取系统核心运行时间
LPFILETIME GetKernelTime(void);
// 获取用户运行时间
LPFILETIME GetUserTime(void);
public:
// 获取系统(空闲,核心以及用户)运行时间
void GetSystemTimes(LPFILETIME IdleTime, LPFILETIME KernelTime, LPFILETIME UserTime, bool ImmediateRet=false);
public:
// 获取CPU占用率
double GetCPURate(void);
public:
// 将64位的长整数转换为64位的实数
double LongInt2Double(LARGE_INTEGER want);
public:
double LongInt2Double(long long want)
{
LARGE_INTEGER _want;
memcpy( &_want, &want, sizeof(LARGE_INTEGER) );
return LongInt2Double( _want );
}
double LongInt2Double(FILETIME want)
{
LARGE_INTEGER _want;
memcpy( &_want, &want, sizeof(LARGE_INTEGER) );
return LongInt2Double( _want);
}
public:
// 获取CPU的频率,高字节部分为主频,低字节部分为次频,以GHz为单位
int GetCPUFrenquence(void);
public:
// 获取当前使用的CPU编号
int GetCurrentUseCPU(void);
public:
// 获取注册表所能够达到的最大尺寸,以字节为单位
long GetMaxRegisterSize(void);
public:
// 获取当前注册表的尺寸,以字节为单位
long GetCurrRegisterSize(void);
private:
long long m_IdleTime;
long long m_KernelTime;
long long m_UserTime;
// 用来表示是否已经获取了系统的信息,true为已经获取,false为没有获取
bool m_bHasSystemInfo;
wchar_t *m_pWChar;
char *m_pchar;
private:
// 系统信息
SYSTEM_INFO m_system_info;
private:
// NTDLL.DLL 句柄
HMODULE m_hNtDll;
// NtQuerySystemInformation 函数地址
NTQUERYSYSTEMINFOMATION NtQuerySystemInformation;
};
/************************************************************************/
/*
* 作者:cpp
* 日期:2008-09-05
* 内容:提供了一个CSystemInformation类,该类可以获取CPU厂家,
* CPU频率,CPU个数,当前使用的CPU,系统运行时占用的
* CPU比率,系统运行的Idle时间,User时间以及Kernel时间
* 获取某个进程的句柄个数,获取随机数(比编译器自带更灵活),
* 将长整数(long long )转换为浮点数,宽字节与窄字节之间的互换
* 注册表最大容量,当前注册表容量
*/
/************************************************************************/
//#include "stdafx.h"
#include <windows.h>
#include "SystemInformation.h"
#include <WinCrypt.h>
#include <winbase.h>
CSystemInformation::CSystemInformation()
: m_bHasSystemInfo(false)
{
m_pWChar = NULL;
m_pchar = NULL;
m_hNtDll = NULL;
m_bHasSystemInfo = false;
::memset( &m_system_info, 0, sizeof(m_system_info));
m_hNtDll = ::LoadLibrary(TEXT("ntdll.dll"));
if( NULL == m_hNtDll)
{
this->ProcessErrorMessage(TEXT("没有载入ntdll.dll文件!"));
return ;
}
this->NtQuerySystemInformation = (NTQUERYSYSTEMINFOMATION) GetProcAddress(
m_hNtDll, "NtQuerySystemInformation"
);
if( NULL== NtQuerySystemInformation )
{
this->ProcessErrorMessage(TEXT("没有找到NtQuerySystemInformation地址!"));
return ;
}
}
CSystemInformation::~CSystemInformation()
{
if( NULL != m_pWChar)
{
delete []m_pWChar;
m_pWChar = NULL;
}
if( NULL != m_pchar )
{
delete []m_pchar;
m_pchar = NULL;
}
if( NULL != m_hNtDll )
{
FreeLibrary(m_hNtDll);
m_hNtDll = NULL;
}
}
void CSystemInformation::ProcessErrorMessage( TCHAR* ErrorText )
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
stringstream ss;
ss << TEXT("警告:") << ErrorText << TEXT("存在下面的错误:\n")
<< lpMsgBuf << std::endl;
MessageBox(NULL, ss.str().c_str(), TEXT("程序错误"), MB_ICONSTOP);
LocalFree(lpMsgBuf);
}
const LPSYSTEM_INFO CSystemInformation::GetSystemInfo( void )
{
::GetSystemInfo( &m_system_info );
m_bHasSystemInfo = true;
return &m_system_info;
}
CSystemInformation::byteString CSystemInformation::GenRandom( int len )
{
HCRYPTPROV hCryptProc;
TCHAR* UserName = TEXT("MyKeyContainer");
if( ! CryptAcquireContext(&hCryptProc, UserName, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET ) )
{
ProcessErrorMessage(TEXT("没有得到加密锁!"));
return byteString();
}
byteString bstr;
try
{
BYTE *pbBuffer = new BYTE[len];
if( !CryptGenRandom( hCryptProc, len, pbBuffer) )
{
ProcessErrorMessage(TEXT("没有产生得到随机数!"));
}
bstr = pbBuffer;
}catch()
{
ProcessErrorMessage(TEXT("GenRandom--没有足够内存!"));
}
CryptReleaseContext(hCryptProc,0);
return bstr;
}
wchar_t* CSystemInformation::ToChar( const char* str, int* len )
{
int strLen = strlen(str);
try
{
if ( NULL != m_pWChar)
{
if( sizeof(m_pWChar)/sizeof(m_pWChar[0]) < strLen+1 )
{
delete[] m_pWChar;
m_pWChar = new wchar_t[strLen+1 ];
}
}
else
{
m_pWChar = new wchar_t[strLen+1 ];
}
*len = strLen + 1;
}
catch()
{
ProcessErrorMessage(TEXT("没有足够内存!"));
*len = 0;
}
return m_pWChar;
}
char* CSystemInformation::ToChar( const wchar_t* str, int* len )
{
int wStrLen = ::wcslen(str);
try
{
if ( sizeof(m_pchar)/sizeof(m_pchar[0]) < wStrLen+1 )
{
delete [] m_pchar;
m_pchar = new char [ wStrLen+1];
}
else
{
m_pchar = new char [ wStrLen+1];
}
*len = wStrLen;
}
catch()
{
ProcessErrorMessage(TEXT("没有足够内存!"));
*len = 0;
}
return m_pchar;
}
// 获取本地机器的CPU类型
CSystemInformation::string CSystemInformation::GetCPUCompany( void )
{
if( ! m_bHasSystemInfo )
this->GetSystemInfo();
WORD processor = HIWORD( m_system_info.dwOemId );
stringstream ss;
switch ( processor )
{
case PROCESSOR_ARCHITECTURE_INTEL:
ss << TEXT("Intel CPU") ;
break;
case PROCESSOR_ARCHITECTURE_AMD64:
ss <<TEXT("Amd64 CPU") ;
break;
case PROCESSOR_ARCHITECTURE_ARM:
ss <<TEXT("Arm CPU") ;
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
ss <<TEXT("Alpha CPU") ;
break;
case PROCESSOR_ARCHITECTURE_IA64:
ss <<TEXT("IA64 CPU") ;
break;
default:
ss << TEXT("unknown CPU") ;
break;
}
return ss.str();
}
// 获取CPU个数
int CSystemInformation::GetCPUNumbers(void)
{
if( !m_bHasSystemInfo )
this->GetSystemInfo();
return m_system_info.dwNumberOfProcessors;
}
// 获取当前CPU编号-即当前使用的是哪个CPU
// 系统最多支持32个CPU
int CSystemInformation::GetCurrentCPU(void)
{
if( !m_bHasSystemInfo )
this->GetSystemInfo();
int current_cpu = 1;
for(int i=0; i< 32; i++)
{
if( m_system_info.dwActiveProcessorMask & ( 1<<i) )
{
current_cpu = i;
break;
}
}
return current_cpu+1;
}
// 获取某个打开进程的句柄个数
long CSystemInformation::GetProcessHandleCount(HANDLE hProcess)
{
DWORD dwProcessCount = 0;
/* if( !::GetProcessHandleCount(hProcess,&dwProcessCount) )
{
ProcessErrorMessage(TEXT("获取进程内句柄个数失败!"));
dwProcessCount = 0;
}
*/
return dwProcessCount;
}
// 获取系统空闲时间
LPFILETIME CSystemInformation::GetIdleTime(void)
{
/*
if( !::GetSystemTimes((LPFILETIME)&m_IdleTime,(LPFILETIME) &m_KernelTime, (LPFILETIME)&m_UserTime))
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
return (LPFILETIME)&m_IdleTime;
}
// 获取系统核心运行时间
LPFILETIME CSystemInformation::GetKernelTime(void)
{
/*
if(! ::GetSystemTimes((LPFILETIME)&m_IdleTime,(LPFILETIME) &m_KernelTime, (LPFILETIME)&m_UserTime))
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
return (LPFILETIME)&m_KernelTime;
}
// 获取用户运行时间
LPFILETIME CSystemInformation::GetUserTime(void)
{
/*
if( ! ::GetSystemTimes((LPFILETIME)&m_IdleTime, (LPFILETIME)&m_KernelTime, (LPFILETIME)&m_UserTime) )
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
return (LPFILETIME)&m_UserTime;
}
// 同时获取获取系统(空闲,核心以及用户)运行时间
void CSystemInformation::GetSystemTimes(LPFILETIME IdleTime, LPFILETIME KernelTime, LPFILETIME UserTime, bool ImmediateRet /*=false*/)
{
/*
if( ! ::GetSystemTimes( IdleTime, KernelTime, UserTime) )
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
if( ImmediateRet )
return ;
memcpy( &m_IdleTime, IdleTime, sizeof( FILETIME) );
memcpy( &m_KernelTime, KernelTime, sizeof( FILETIME) );
memcpy( &m_UserTime, UserTime, sizeof(FILETIME) );
}
// 获取CPU占用率
double CSystemInformation::GetCPURate(void)
{
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double IdleTime = 0 ;
static double OldIdleTime = 0;
double SystemTime = 0;
static double OldSystemTime = 0;
if( NtQuerySystemInformation )
{
DWORD status = NtQuerySystemInformation(SystemBasicInformation, &SysBaseInfo,
sizeof(SYSTEM_BASIC_INFORMATION), NULL);
//GetSystemInfo();
if ( NO_ERROR != status)
{
ProcessErrorMessage(TEXT("没有获取到系统基础信息!"));
return 0;
}
//GetIdleTime(); // 获取系统的三个时间
status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo,
sizeof(SYSTEM_TIME_INFORMATION), NULL);
if ( NO_ERROR != status)
{
ProcessErrorMessage(TEXT("没有获取到系统基础信息!"));
return 0;
}
status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo,
sizeof(SYSTEM_PERFORMANCE_INFORMATION), NULL);
if ( NO_ERROR != status)
{
ProcessErrorMessage(TEXT("没有获取到系统基础信息!"));
return 0;
}
if ( 0 != OldIdleTime )
{
IdleTime = LongInt2Double(SysPerfInfo.IdleTime) - OldIdleTime;
SystemTime = LongInt2Double(SysTimeInfo.liKeSystemTime) - OldSystemTime;
// 采用这种方式获取的CPU占用率,获取的值与任务管理相差较大
//SystemTime = LongInt2Double(m_KernelTime) - OldSystemTime;
IdleTime = IdleTime/SystemTime;
IdleTime = 100 - IdleTime*100.0/(double)SysBaseInfo.NumberOfProcessors;
}
OldIdleTime = LongInt2Double(SysPerfInfo.IdleTime);
OldSystemTime =LongInt2Double( SysTimeInfo.liKeSystemTime );
//OldSystemTime = LongInt2Double(m_KernelTime);
//Sleep(100);
}
return IdleTime;
}
// 将64位的长整数转换为64位的实数
double CSystemInformation::LongInt2Double(LARGE_INTEGER want)
{
return ((double)(want.HighPart) * 4.294967296E9 + (double)(want.LowPart) );
}
// 获取CPU的频率,高word部分为主频,低word部分为次频,以GHz为单位
int CSystemInformation::GetCPUFrenquence(void)
{
if ( !m_bHasSystemInfo )
{
this->GetSystemInfo();
}
/************************************************************************
#ifdef _DEBUG
stringstream ss;
ss << HIBYTE(m_system_info.wProcessorRevision) <<LOBYTE(m_system_info.wProcessorRevision) << std::endl;
AfxMessageBox( ss.str().c_str() );
#endif // _DEBUG
*/
return m_system_info.wProcessorRevision;
}
// 获取注册表所能够达到的最大尺寸,以字节为单位
long CSystemInformation::GetMaxRegisterSize(void)
{
unsigned long Max = 0;
unsigned long Curr = 0;
/* if ( !GetSystemRegistryQuota(&Max, &Curr) )
{
ProcessErrorMessage(TEXT("没有获取到系统的注册表存储容量信息!"));
return 0;
}
*/
return Max;
}
// 获取当前注册表的尺寸,以字节为单位
long CSystemInformation::GetCurrRegisterSize(void)
{
unsigned long Max = 0;
unsigned long Curr = 0;
/*
if ( !GetSystemRegistryQuota(&Max, &Curr) )
{
ProcessErrorMessage(TEXT("没有获取到系统的注册表存储容量信息!"));
return 0;
}
*/
return Curr;
}
需要注意的是,其中还有部分成员函数不能够良好工作,但CPU占用率已经可以非常良好的运行,与windows的任务管理器基本上没有什么大的差别,但未对百分比数据进行修订,以使得数据位数达到一致!
/*
* 作者:cpp
* 日期:2008-09-05
* 内容:提供了一个CSystemInformation类,该类可以获取CPU厂家,
* CPU频率,CPU个数,当前使用的CPU,系统运行时占用的
* CPU比率,系统运行的Idle时间,User时间以及Kernel时间
* 获取某个进程的句柄个数,获取随机数(比编译器自带更灵活),
* 将长整数(long long )转换为浮点数,宽字节与窄字节之间的互换
* 注册表最大容量,当前注册表容量
*/
/************************************************************************/
//#include "stdafx.h"
#include <windows.h>
#include "SystemInformation.h"
#include <WinCrypt.h>
#include <winbase.h>
CSystemInformation::CSystemInformation()
: m_bHasSystemInfo(false)
{
m_pWChar = NULL;
m_pchar = NULL;
m_hNtDll = NULL;
m_bHasSystemInfo = false;
::memset( &m_system_info, 0, sizeof(m_system_info));
m_hNtDll = ::LoadLibrary(TEXT("ntdll.dll"));
if( NULL == m_hNtDll)
{
this->ProcessErrorMessage(TEXT("没有载入ntdll.dll文件!"));
return ;
}
this->NtQuerySystemInformation = (NTQUERYSYSTEMINFOMATION) GetProcAddress(
m_hNtDll, "NtQuerySystemInformation"
);
if( NULL== NtQuerySystemInformation )
{
this->ProcessErrorMessage(TEXT("没有找到NtQuerySystemInformation地址!"));
return ;
}
}
CSystemInformation::~CSystemInformation()
{
if( NULL != m_pWChar)
{
delete []m_pWChar;
m_pWChar = NULL;
}
if( NULL != m_pchar )
{
delete []m_pchar;
m_pchar = NULL;
}
if( NULL != m_hNtDll )
{
FreeLibrary(m_hNtDll);
m_hNtDll = NULL;
}
}
void CSystemInformation::ProcessErrorMessage( TCHAR* ErrorText )
{
LPVOID lpMsgBuf;
FormatMessage(
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM,
NULL,
GetLastError(),
MAKELANGID(LANG_NEUTRAL, SUBLANG_DEFAULT), // Default language
(LPTSTR) &lpMsgBuf,
0,
NULL
);
stringstream ss;
ss << TEXT("警告:") << ErrorText << TEXT("存在下面的错误:\n")
<< lpMsgBuf << std::endl;
MessageBox(NULL, ss.str().c_str(), TEXT("程序错误"), MB_ICONSTOP);
LocalFree(lpMsgBuf);
}
const LPSYSTEM_INFO CSystemInformation::GetSystemInfo( void )
{
::GetSystemInfo( &m_system_info );
m_bHasSystemInfo = true;
return &m_system_info;
}
CSystemInformation::byteString CSystemInformation::GenRandom( int len )
{
HCRYPTPROV hCryptProc;
TCHAR* UserName = TEXT("MyKeyContainer");
if( ! CryptAcquireContext(&hCryptProc, UserName, NULL, PROV_RSA_FULL, CRYPT_NEWKEYSET ) )
{
ProcessErrorMessage(TEXT("没有得到加密锁!"));
return byteString();
}
byteString bstr;
try
{
BYTE *pbBuffer = new BYTE[len];
if( !CryptGenRandom( hCryptProc, len, pbBuffer) )
{
ProcessErrorMessage(TEXT("没有产生得到随机数!"));
}
bstr = pbBuffer;
}catch()
{
ProcessErrorMessage(TEXT("GenRandom--没有足够内存!"));
}
CryptReleaseContext(hCryptProc,0);
return bstr;
}
wchar_t* CSystemInformation::ToChar( const char* str, int* len )
{
int strLen = strlen(str);
try
{
if ( NULL != m_pWChar)
{
if( sizeof(m_pWChar)/sizeof(m_pWChar[0]) < strLen+1 )
{
delete[] m_pWChar;
m_pWChar = new wchar_t[strLen+1 ];
}
}
else
{
m_pWChar = new wchar_t[strLen+1 ];
}
*len = strLen + 1;
}
catch()
{
ProcessErrorMessage(TEXT("没有足够内存!"));
*len = 0;
}
return m_pWChar;
}
char* CSystemInformation::ToChar( const wchar_t* str, int* len )
{
int wStrLen = ::wcslen(str);
try
{
if ( sizeof(m_pchar)/sizeof(m_pchar[0]) < wStrLen+1 )
{
delete [] m_pchar;
m_pchar = new char [ wStrLen+1];
}
else
{
m_pchar = new char [ wStrLen+1];
}
*len = wStrLen;
}
catch()
{
ProcessErrorMessage(TEXT("没有足够内存!"));
*len = 0;
}
return m_pchar;
}
// 获取本地机器的CPU类型
CSystemInformation::string CSystemInformation::GetCPUCompany( void )
{
if( ! m_bHasSystemInfo )
this->GetSystemInfo();
WORD processor = HIWORD( m_system_info.dwOemId );
stringstream ss;
switch ( processor )
{
case PROCESSOR_ARCHITECTURE_INTEL:
ss << TEXT("Intel CPU") ;
break;
case PROCESSOR_ARCHITECTURE_AMD64:
ss <<TEXT("Amd64 CPU") ;
break;
case PROCESSOR_ARCHITECTURE_ARM:
ss <<TEXT("Arm CPU") ;
break;
case PROCESSOR_ARCHITECTURE_ALPHA:
ss <<TEXT("Alpha CPU") ;
break;
case PROCESSOR_ARCHITECTURE_IA64:
ss <<TEXT("IA64 CPU") ;
break;
default:
ss << TEXT("unknown CPU") ;
break;
}
return ss.str();
}
// 获取CPU个数
int CSystemInformation::GetCPUNumbers(void)
{
if( !m_bHasSystemInfo )
this->GetSystemInfo();
return m_system_info.dwNumberOfProcessors;
}
// 获取当前CPU编号-即当前使用的是哪个CPU
// 系统最多支持32个CPU
int CSystemInformation::GetCurrentCPU(void)
{
if( !m_bHasSystemInfo )
this->GetSystemInfo();
int current_cpu = 1;
for(int i=0; i< 32; i++)
{
if( m_system_info.dwActiveProcessorMask & ( 1<<i) )
{
current_cpu = i;
break;
}
}
return current_cpu+1;
}
// 获取某个打开进程的句柄个数
long CSystemInformation::GetProcessHandleCount(HANDLE hProcess)
{
DWORD dwProcessCount = 0;
/* if( !::GetProcessHandleCount(hProcess,&dwProcessCount) )
{
ProcessErrorMessage(TEXT("获取进程内句柄个数失败!"));
dwProcessCount = 0;
}
*/
return dwProcessCount;
}
// 获取系统空闲时间
LPFILETIME CSystemInformation::GetIdleTime(void)
{
/*
if( !::GetSystemTimes((LPFILETIME)&m_IdleTime,(LPFILETIME) &m_KernelTime, (LPFILETIME)&m_UserTime))
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
return (LPFILETIME)&m_IdleTime;
}
// 获取系统核心运行时间
LPFILETIME CSystemInformation::GetKernelTime(void)
{
/*
if(! ::GetSystemTimes((LPFILETIME)&m_IdleTime,(LPFILETIME) &m_KernelTime, (LPFILETIME)&m_UserTime))
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
return (LPFILETIME)&m_KernelTime;
}
// 获取用户运行时间
LPFILETIME CSystemInformation::GetUserTime(void)
{
/*
if( ! ::GetSystemTimes((LPFILETIME)&m_IdleTime, (LPFILETIME)&m_KernelTime, (LPFILETIME)&m_UserTime) )
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
return (LPFILETIME)&m_UserTime;
}
// 同时获取获取系统(空闲,核心以及用户)运行时间
void CSystemInformation::GetSystemTimes(LPFILETIME IdleTime, LPFILETIME KernelTime, LPFILETIME UserTime, bool ImmediateRet /*=false*/)
{
/*
if( ! ::GetSystemTimes( IdleTime, KernelTime, UserTime) )
{
ProcessErrorMessage(TEXT("获取系统运行时间错误!"));
}
*/
if( ImmediateRet )
return ;
memcpy( &m_IdleTime, IdleTime, sizeof( FILETIME) );
memcpy( &m_KernelTime, KernelTime, sizeof( FILETIME) );
memcpy( &m_UserTime, UserTime, sizeof(FILETIME) );
}
// 获取CPU占用率
double CSystemInformation::GetCPURate(void)
{
SYSTEM_PERFORMANCE_INFORMATION SysPerfInfo;
SYSTEM_TIME_INFORMATION SysTimeInfo;
SYSTEM_BASIC_INFORMATION SysBaseInfo;
double IdleTime = 0 ;
static double OldIdleTime = 0;
double SystemTime = 0;
static double OldSystemTime = 0;
if( NtQuerySystemInformation )
{
DWORD status = NtQuerySystemInformation(SystemBasicInformation, &SysBaseInfo,
sizeof(SYSTEM_BASIC_INFORMATION), NULL);
//GetSystemInfo();
if ( NO_ERROR != status)
{
ProcessErrorMessage(TEXT("没有获取到系统基础信息!"));
return 0;
}
//GetIdleTime(); // 获取系统的三个时间
status = NtQuerySystemInformation(SystemTimeInformation, &SysTimeInfo,
sizeof(SYSTEM_TIME_INFORMATION), NULL);
if ( NO_ERROR != status)
{
ProcessErrorMessage(TEXT("没有获取到系统基础信息!"));
return 0;
}
status = NtQuerySystemInformation(SystemPerformanceInformation, &SysPerfInfo,
sizeof(SYSTEM_PERFORMANCE_INFORMATION), NULL);
if ( NO_ERROR != status)
{
ProcessErrorMessage(TEXT("没有获取到系统基础信息!"));
return 0;
}
if ( 0 != OldIdleTime )
{
IdleTime = LongInt2Double(SysPerfInfo.IdleTime) - OldIdleTime;
SystemTime = LongInt2Double(SysTimeInfo.liKeSystemTime) - OldSystemTime;
// 采用这种方式获取的CPU占用率,获取的值与任务管理相差较大
//SystemTime = LongInt2Double(m_KernelTime) - OldSystemTime;
IdleTime = IdleTime/SystemTime;
IdleTime = 100 - IdleTime*100.0/(double)SysBaseInfo.NumberOfProcessors;
}
OldIdleTime = LongInt2Double(SysPerfInfo.IdleTime);
OldSystemTime =LongInt2Double( SysTimeInfo.liKeSystemTime );
//OldSystemTime = LongInt2Double(m_KernelTime);
//Sleep(100);
}
return IdleTime;
}
// 将64位的长整数转换为64位的实数
double CSystemInformation::LongInt2Double(LARGE_INTEGER want)
{
return ((double)(want.HighPart) * 4.294967296E9 + (double)(want.LowPart) );
}
// 获取CPU的频率,高word部分为主频,低word部分为次频,以GHz为单位
int CSystemInformation::GetCPUFrenquence(void)
{
if ( !m_bHasSystemInfo )
{
this->GetSystemInfo();
}
/************************************************************************
#ifdef _DEBUG
stringstream ss;
ss << HIBYTE(m_system_info.wProcessorRevision) <<LOBYTE(m_system_info.wProcessorRevision) << std::endl;
AfxMessageBox( ss.str().c_str() );
#endif // _DEBUG
*/
return m_system_info.wProcessorRevision;
}
// 获取注册表所能够达到的最大尺寸,以字节为单位
long CSystemInformation::GetMaxRegisterSize(void)
{
unsigned long Max = 0;
unsigned long Curr = 0;
/* if ( !GetSystemRegistryQuota(&Max, &Curr) )
{
ProcessErrorMessage(TEXT("没有获取到系统的注册表存储容量信息!"));
return 0;
}
*/
return Max;
}
// 获取当前注册表的尺寸,以字节为单位
long CSystemInformation::GetCurrRegisterSize(void)
{
unsigned long Max = 0;
unsigned long Curr = 0;
/*
if ( !GetSystemRegistryQuota(&Max, &Curr) )
{
ProcessErrorMessage(TEXT("没有获取到系统的注册表存储容量信息!"));
return 0;
}
*/
return Curr;
}
需要注意的是,其中还有部分成员函数不能够良好工作,但CPU占用率已经可以非常良好的运行,与windows的任务管理器基本上没有什么大的差别,但未对百分比数据进行修订,以使得数据位数达到一致!
/*
*
* Copyright (c) 2011 Ubunoon.
* All rights reserved.
*
* email: netubu#gmail.com replace '#' to '@'
* http://www.cnblogs.com/ubunoon
* 欢迎来邮件定制各类验证码识别,条码识别,图像处理等软件
* 推荐不错的珍珠饰品,欢迎订购 * 宜臣珍珠(淡水好珍珠) */
*
* Copyright (c) 2011 Ubunoon.
* All rights reserved.
*
* email: netubu#gmail.com replace '#' to '@'
* http://www.cnblogs.com/ubunoon
* 欢迎来邮件定制各类验证码识别,条码识别,图像处理等软件
* 推荐不错的珍珠饰品,欢迎订购 * 宜臣珍珠(淡水好珍珠) */