C++/QT 获取系统CPU、内存、磁盘、进程相关信息

       最近在学习用C++获取WINDOWS和LINUX  下的系统信息,对其大概方法做了一些总结,希望对新人有一些帮助,话不多说,先来代码大笑大笑。。。。。。。。。。。。。。。。。。。

      首先,我针对两个平台定义了一个接口类,即纯虚函数类,其windows 和 linux 的实现类可以实现该类,接口代码如下:

#pragma once
#pragma comment(lib,"Kernel32.lib")
#pragma comment(lib,"Psapi.lib")
#include <Windows.h>
#include <TlHelp32.h>
#include<direct.h>
#include<winternl.h>
#include <Psapi.h>
#include <QMap>
//获取系统信息的接口
class ISysInfo
{
public:
	virtual ~ISysInfo(){}
	/************************************************************************/
	/*函数说明:获取系统CPU当前使用率
	/*函数参数:nCpuRate->CPU使用率
	/*返回结果:返回结果状态
	/*作者时间:Bevis 2014-07-19
	/************************************************************************/
	virtual bool GetSysCpu(int& nCpuRate) = 0;
	/************************************************************************/
	/*函数说明:获取系统内存信息
	/*函数参数:nMemTotal->内存总共大小,(MB);nMemUsed->内存已使用大小,(MB)
	/*返回结果:返回结果状态
	/*作者时间:Bevis 2014-07-19
	/************************************************************************/
	virtual bool GetSysMemory(int& nMemTotal,int& nMemUsed) = 0;
	/************************************************************************/
	/*函数说明:获取系统磁盘信息
	/*函数参数:nDiskTotal->磁盘总共大小,(MB);nDiskUsed->磁盘已使用大小,(MB)
	/*返回结果:返回结果状态
	/*作者时间:Bevis 2014-07-19
	/************************************************************************/
	virtual bool GetSysDisk(int& nDiskTotal,int& nDiskUsed) = 0;
	/************************************************************************/
	/*函数说明:遍历系统所有进程
	/*函数参数:无
	/*返回结果:进程PID和进程名称的映射集合
	/*作者时间:Bevis 2014-07-19
	/************************************************************************/
	virtual QMap<int,QString> GetAllProcess() = 0;
	/************************************************************************/
	/*函数说明:获取单个进程的内存使用率
	/*函数参数:nPid->进程唯一标识号;nProcessMemRate->进程的内存使用率
	/*返回结果:返回结果状态
	/*作者时间:Bevis 2014-07-19
	/************************************************************************/
	virtual bool GetProcessMemory(int nPid,int& nProcessMemRate) = 0;
};

由于时间有限,暂时只实现了WINDOWS平台,后续我会补上LINUX的实现....微笑微笑微笑

windows的实现类头文件定义如下:

#pragma once
#include <QDebug>
#include <QString>
#include "ISysInfo.h"
#include <atlconv.h>
#include <string.h>

//在WINDOWS平台上实现
class ISysWin: public ISysInfo
{
public:
	ISysWin(void);
	virtual ~ISysWin(void);

	bool GetSysCpu(int& nCpuRate) ;

	bool GetSysMemory(int& nMemTotal,int& nMemUsed);

	bool GetSysDisk(int& nDiskTotal,int& nDiskUsed) ;

	QMap<int,QString> GetAllProcess() ;

	bool GetProcessMemory(int nPid,int& nProcessMemRate) ;

protected:
	//时间转换
	__int64 Filetime2Int64(const FILETIME* ftime);
	//两个时间相减运算
	__int64 CompareFileTime(FILETIME preTime,FILETIME nowTime);
};

windows的实现类cpp文件定义如下:

#include "ISysWin.h"


ISysWin::ISysWin(void)
{
}


ISysWin::~ISysWin(void)
{
}

__int64 ISysWin::Filetime2Int64(const FILETIME* ftime)
{
	LARGE_INTEGER li;
	li.LowPart = ftime->dwLowDateTime;
	li.HighPart = ftime->dwHighDateTime;
	return li.QuadPart;
}

__int64 ISysWin::CompareFileTime(FILETIME preTime,FILETIME nowTime)
{
	return this->Filetime2Int64(&nowTime) - this->Filetime2Int64(&preTime);
}

//将单字节char*转化为宽字节wchar_t*  
wchar_t* AnsiToUnicode( const char* szStr )  
{  
	int nLen = MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szStr, -1, NULL, 0 );  
	if (nLen == 0)  
	{  
		return NULL;  
	}  
	wchar_t* pResult = new wchar_t[nLen];  
	MultiByteToWideChar( CP_ACP, MB_PRECOMPOSED, szStr, -1, pResult, nLen );  
	return pResult;  
}  

//将宽字节wchar_t*转化为单字节char*  
inline char* UnicodeToAnsi( const wchar_t* szStr )  
{  
	int nLen = WideCharToMultiByte( CP_ACP, 0, szStr, -1, NULL, 0, NULL, NULL );  
	if (nLen == 0)  
	{  
		return NULL;  
	}  
	char* pResult = new char[nLen];  
	WideCharToMultiByte( CP_ACP, 0, szStr, -1, pResult, nLen, NULL, NULL );  
	return pResult;  
}  

bool ISysWin::GetSysCpu(int& nCpuRate) 
{
	HANDLE hEvent;
	bool res;
	static FILETIME preIdleTime;
	static FILETIME preKernelTime;
	static FILETIME preUserTime;

	FILETIME idleTime;
	FILETIME kernelTime;
	FILETIME userTime;

	res = GetSystemTimes(&idleTime,&kernelTime,&userTime);

	preIdleTime = idleTime;
	preKernelTime = kernelTime;
	preUserTime = userTime;

	hEvent = CreateEvent(NULL,FALSE,FALSE,NULL);//初始值为nonsignaled

	WaitForSingleObject(hEvent,500);//等待500毫秒

	res = GetSystemTimes(&idleTime,&kernelTime,&userTime);

	int idle = CompareFileTime(preIdleTime,idleTime);
	int kernel = CompareFileTime(preKernelTime,kernelTime);
	int user = CompareFileTime(preUserTime,userTime);

	nCpuRate =(int)ceil( 100.0*( kernel + user - idle ) / ( kernel + user ) );

	return res;
}

bool ISysWin::GetSysMemory(int& nMemTotal,int& nMemUsed)
{
	MEMORYSTATUSEX memsStat;
	memsStat.dwLength = sizeof(memsStat);
	if(!GlobalMemoryStatusEx(&memsStat))//如果获取系统内存信息不成功,就直接返回
	{
		nMemTotal = -1;
		nMemUsed  = -1;
		return false;
	}
	int nMemFree = memsStat.ullAvailPhys/( 1024.0*1024.0 );
	nMemTotal = memsStat.ullTotalPhys/( 1024.0*1024.0 );
	nMemUsed= nMemTotal- nMemFree;
	return true;
}

bool ISysWin::GetSysDisk(int& nDiskTotal,int& nDiskUsed) 
{
	static char path[_MAX_PATH];//存储当前系统存在的盘符
	int curdrive = _getdrive();
	unsigned long lFreeAll = 0UL;
	unsigned long lTotalAll = 0UL;
	for(int drive = 1; drive <= 26; drive++ )//遍历所有盘符
	{
		if( !_chdrive( drive ) )
		{
			sprintf(path, "%c:\\", drive + 'A' - 1 );
			ULARGE_INTEGER caller, total, free;
			WCHAR wszClassName[_MAX_PATH];  
			memset(wszClassName,0,sizeof(wszClassName));  
			MultiByteToWideChar(CP_ACP,0,path,strlen(path)+1,wszClassName,  
				sizeof(wszClassName)/sizeof(wszClassName[0]));  
			if (GetDiskFreeSpaceEx(wszClassName, &caller, &total, &free) == 0)
			{
				qDebug()<<"GetDiskFreeSpaceEx Filed!";
				return false;
			}

			double dTepFree = free.QuadPart/( 1024.0*1024.0 );
			double dTepTotal = total.QuadPart/( 1024.0*1024.0 );
			//qDebug()<<"Get Windows Disk Information:"<<path<<"--free:"<<dTepFree<<"--total:"<<dTepTotal;
			lFreeAll += (unsigned long)ceil(dTepFree);
			lTotalAll += (unsigned long)ceil(dTepTotal);
		}
	}
	nDiskUsed = lFreeAll;
	nDiskTotal= lTotalAll;
	return true;
}

QMap<int,QString> ISysWin::GetAllProcess() 
{
	HANDLE hProcessSnap;	//进程快照的句柄
	HANDLE hProcess;	//用于获取进程的句柄
	PROCESSENTRY32 pe32;//进程信息的结构体
	QMap<int,QString> pidMap;//保存所有进程的PID
	// 获取系统进程信息的快照
	hProcessSnap = CreateToolhelp32Snapshot( TH32CS_SNAPPROCESS, 0 );
	if( hProcessSnap == INVALID_HANDLE_VALUE )
	{
		qDebug()<<"CreateToolhelp32Snapshot Failed!";// 打印错误信息
		if(NULL !=hProcessSnap)
		{
			CloseHandle( hProcessSnap );          // 关闭进程快照信息
			hProcessSnap = NULL;
		}
		return pidMap;
	}
	// 在使用之前设置PROCESSENTRY32结构体的初始大小值,如果不初始化dwSize, Process32First 调用会失败.
	pe32.dwSize = sizeof( PROCESSENTRY32 );
	if( !Process32First( hProcessSnap, &pe32 ) )// 开始获取第一个进程的信息,如果获取失败就返回
	{
		qDebug()<<"Process32First Failed!"; // 打印错误信息
		if(NULL !=hProcessSnap)
		{
			CloseHandle( hProcessSnap );          // 关闭进程快照信息
			hProcessSnap = NULL;
		}
		return pidMap;
	}
	//开始遍历所有进程
	pidMap.clear();
	do
	{
		//加入PID
		if(!pidMap.contains((int)pe32.th32ProcessID))
		{
			QString strProcessName =UnicodeToAnsi(pe32.szExeFile);
			pidMap.insert((int)pe32.th32ProcessID,strProcessName);
		}
		
		//当然还可以获取到很多其他信息,例如进程名字(szExeFile[MAX_PATH])、父进程PPID(th32ParentProcessID)。。。
		/* 附上该结构体信息
		typedef struct tagPROCESSENTRY32 {
		DWORD     dwSize;
		DWORD     cntUsage;
		DWORD     th32ProcessID;
		ULONG_PTR th32DefaultHeapID;
		DWORD     th32ModuleID;
		DWORD     cntThreads;
		DWORD     th32ParentProcessID;
		LONG      pcPriClassBase;
		DWORD     dwFlags;
		TCHAR     szExeFile[MAX_PATH];
		} PROCESSENTRY32, *PPROCESSENTRY32;
		*/
	} 
	while( Process32Next( hProcessSnap, &pe32 ) );// 获取下一个进程的信息
	if(NULL !=hProcessSnap)//最后关闭快照句柄
	{
		CloseHandle( hProcessSnap );
		hProcessSnap = NULL;
	}
	return pidMap;
}

bool ISysWin::GetProcessMemory(int nPid,int& nProcessMemRate) 
{
	HANDLE hProcess;//该线程的句柄
	PROCESS_MEMORY_COUNTERS pmc;//该线程的内存信息结构体
	hProcess = OpenProcess( PROCESS_ALL_ACCESS ,FALSE, nPid );//利用最大权限打开该线程并获得句柄
	if (NULL == hProcess)
	{
		qDebug()<<"OpenProcess Failed!";
		return false;
	}
	if ( !GetProcessMemoryInfo( hProcess, &pmc, sizeof(pmc)) )
	{
		qDebug()<<"GetProcessMemoryInfo Failed!";
		return false;
	}

	int nMemTotal = 0;
	int nMemUsed = 0;
	this->GetSysMemory(nMemTotal,nMemUsed);
	double tep = ((int)pmc.WorkingSetSize*1.0);
	nProcessMemRate = (int)ceil(100*(tep/(1024.0*1024.0)) / nMemTotal) ;

	CloseHandle(hProcess);

	return true;
}


最后当然是我的测试类了,

#include <QtCore/QCoreApplication>
#include "ISysInfo.h"
#include "ISysWin.h"
#include <Windows.h>
int main(int argc, char *argv[])
{
	QCoreApplication a(argc, argv);
	ISysInfo* pISys = new ISysWin();//调用WINDOWS实现的子类
	while (1)
	{
		int nCpuRate = -1;
		int nMemTotal = -1;
		int nMemUsed = -1;
		int nDiskTotal = -1;
		int nDiskUsed = -1;
		int nProcessMemRate = -1;
		QMap<int,QString> pidMap;

		pISys->GetSysCpu(nCpuRate);
		qDebug()<<"CPU Rate:"<<nCpuRate<<"%";

		pISys->GetSysMemory(nMemTotal,nMemUsed);
		qDebug()<<"Mem Total:"<<nMemTotal<<"\t Mem Used:"<<nMemUsed;

		pISys->GetSysDisk(nDiskTotal,nDiskUsed);
		qDebug()<<"Disk Total:"<<(nDiskTotal/1024.0)<<"GB \t Disk Used:"<<(nDiskUsed/1024.0)<<"GB";

		pISys->GetProcessMemory(6472,nProcessMemRate);
		qDebug()<<"PID:6472;\t Mem Rate:"<<nProcessMemRate<<"%";

		pidMap = pISys->GetAllProcess();
		qDebug()<<"Process Number:"<<pidMap.size();

		qDebug()<<"-------------------------------------------------------------------";
		Sleep(1000);
	}	
	delete pISys;
	return a.exec(); 
}<span style="color:#ff0000;">
</span>

后期我会继续实现linux下的代码,请继续关注!!!


  • 24
    点赞
  • 106
    收藏
    觉得还不错? 一键收藏
  • 14
    评论
评论 14
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值