windows 获取CPU 内存 磁盘 网卡状态

该博客介绍了如何实现一个实时系统资源监控器,包括CPU使用率、内存占用、磁盘空间以及网络流量的监测。通过Windows API和Pdh库获取系统信息,使用线程进行数据采集,并提供回调函数传递监控数据。此外,还提供了获取网络接口和磁盘空间的辅助函数。此监控器可应用于系统性能分析和管理。
摘要由CSDN通过智能技术生成

头文件 :


#include <stdio.h>
#include <Windows.h> 
#include <time.h>
#include <tchar.h>
#include <string>
#include <iostream>
#include <thread>


typedef void (*MessageCallback)(float cpu_usage, float mem_usage, float disk_usage, float network_usage);


typedef struct
{

	float cpu;
	float memory;
	float disk;
	unsigned long send;
	unsigned long recv;

}SYSINFO;


class  SysInfo {
public:
	SysInfo();
	~SysInfo();

	bool Start(MessageCallback cb);
	void Stop();
	bool m_run_flag = false;

	SYSINFO* GetInfo();

	SYSINFO m_sys_info = {0};
	MessageCallback m_message_callback = nullptr;

private:


	std::thread* m_thread = nullptr;

	std::thread* m_sys_thread = nullptr;
};

源文件:


#include "si.h"


#include <Pdh.h>

#include <PdhMsg.h>

#include <IPHlpApi.h>

#include <comutil.h>

#include <tchar.h>

#pragma comment(lib,"pdh.lib")

#pragma comment(lib,"IPHlpApi.lib")

#pragma comment(lib,"comsuppw.lib")


FILETIME m_preidleTime;
FILETIME m_prekernelTime;
FILETIME m_preuserTime;


using namespace std;

__int64 compareFileTime2(FILETIME time1, FILETIME time2)
{
	__int64 a = time1.dwHighDateTime << 32 | time1.dwLowDateTime;
	__int64 b = time2.dwHighDateTime << 32 | time2.dwLowDateTime;


	return   b - a;
}

double cpuUseage()
{
	FILETIME idleTime;
	FILETIME kernelTime;
	FILETIME userTime;
	GetSystemTimes(&idleTime, &kernelTime, &userTime);


	int idle = compareFileTime2(m_preidleTime, idleTime);
	int kernel = compareFileTime2(m_prekernelTime, kernelTime);
	int user = compareFileTime2(m_preuserTime, userTime);


	if (kernel + user == 0)
		return 0.0;
	
	double cpu = abs((kernel + user - idle) * 100 / (kernel + user));

	m_preidleTime = idleTime;
	m_prekernelTime = kernelTime;
	m_preuserTime = userTime;
	return cpu;
}


BOOL get_disk_space(char driver, __int64& allSpace, __int64& freeSpace)
{
	BOOL ret = false;
	DWORD dwSector;
	DWORD dwBytesInSec;
	DWORD dwCluster;
	DWORD dwFreeCluster;
	string sDriver;
	sDriver += driver;
	sDriver += ":\\";

	ret = GetDiskFreeSpaceA(sDriver.c_str(), &dwSector, &dwBytesInSec, &dwFreeCluster, &dwCluster);
	allSpace = 0;
	freeSpace = 0;

	allSpace = dwSector;
	allSpace *= dwBytesInSec;
	allSpace *= dwCluster;

	freeSpace = dwSector;
	freeSpace *= dwBytesInSec;
	freeSpace *= dwFreeCluster;

	return ret;
}



string getNetInterface() {
	ULONG ulSize = 0;
	IP_ADAPTER_INFO* pAdapter = nullptr;
	if (GetAdaptersInfo(pAdapter, &ulSize) == ERROR_BUFFER_OVERFLOW) {
		pAdapter = (IP_ADAPTER_INFO*)new char[ulSize];
	}
	else {
		cout << "GetAdaptersInfo fail" << endl;
		return "";
	}

	if (GetAdaptersInfo(pAdapter, &ulSize) != ERROR_SUCCESS) {
		cout << "GetAdaptersInfo fail" << endl;
		return "";
	}

	IPAddr ipAddr = { 0 };
	DWORD dwIndex = -1;
	DWORD nRet = GetBestInterface(ipAddr, &dwIndex);
	if (NO_ERROR != nRet) {
		cout << "GetBestInterface fail: " << nRet << endl;
	}

	string strInterface;
	for (auto* pCur = pAdapter; pCur != NULL; pCur = pCur->Next) {
		//if (pCur->Type != MIB_IF_TYPE_ETHERNET)
		//  continue;

		if (pCur->Index == dwIndex) {
			cout << "Best Interface!! ";
			strInterface = pCur->Description;
		}

		cout << "Descrip: " << pCur->Description;
		cout << ", Name: " << pCur->AdapterName << endl;
		cout << "IP: " << pCur->IpAddressList.IpAddress.String;
		cout << ", Gateway: " << pCur->GatewayList.IpAddress.String << endl << endl;
	}

	delete []pAdapter;
	return strInterface;
}


void getResourceCounter(void *param)
{
	HQUERY query;
	PDH_STATUS status = PdhOpenQuery(NULL, NULL, &query);
	if (status != ERROR_SUCCESS)
		cout << "Open Query Error" << endl;

	HCOUNTER cpuCounter, memCounter;
	HCOUNTER recvCounter, sentCounter;

	SysInfo* info = (SysInfo*)param;

	string strGet = getNetInterface();
	string strInterface = "\\Network Interface(" + strGet + ")\\";
	cout << strInterface << endl;

	
	status = PdhAddCounterA(query, (strInterface + "Bytes Received/sec").c_str(), NULL, &recvCounter);
	if (status != ERROR_SUCCESS)
		cout << "Add Received Counter Error" << endl;
	status = PdhAddCounterA(query, (strInterface + "Bytes Sent/sec").c_str(), NULL, &sentCounter);
	if (status != ERROR_SUCCESS)
		cout << "Add Sent Counter Error" << endl;


	int nIndex = 0;
	// cout << setiosflags(ios::fixed) << setprecision(4);
	while (info->m_run_flag) {
		PdhCollectQueryData(query);
		Sleep(1000);

		PdhCollectQueryData(query);

		PDH_FMT_COUNTERVALUE pdhValue;
		DWORD dwValue;

		status = PdhGetFormattedCounterValue(recvCounter, PDH_FMT_LONG, &dwValue, &pdhValue);
		if (status == ERROR_SUCCESS)
		{
			info->m_sys_info.recv = pdhValue.longValue;
		}
		


		status = PdhGetFormattedCounterValue(sentCounter, PDH_FMT_LONG, &dwValue, &pdhValue);
		if (status == ERROR_SUCCESS)
		{
			info->m_sys_info.send = pdhValue.longValue;
		}

		Sleep(1000 * 1);
	}

	PdhCloseQuery(query);
}



float QMCY_GetCPU()
{
	float cpu_usage = cpuUseage();
	return (float)cpu_usage / 100;
}

float QMCY_GetMemory()
{
	MEMORYSTATUSEX statex;
	statex.dwLength = sizeof(statex);
	GlobalMemoryStatusEx(&statex);
	float memory_usage = (float)statex.dwMemoryLoad / 100;

	return memory_usage;
}



float QMCY_GetDisk()
{
	__int64 allSpace = 0, freeSpace = 0, driveFree, driveTotal;
	DWORD dwDriveStrLen;
	TCHAR wDrivesName[0x100];
	int DType;
	dwDriveStrLen = sizeof(wDrivesName);
	GetLogicalDriveStrings(dwDriveStrLen, wDrivesName);
	TCHAR* p = (TCHAR*)wDrivesName;
	while (*p)
	{
		string s = (char*)p;
		DType = GetDriveType(LPTSTR(p));
		if (DType == DRIVE_FIXED)
		{
			get_disk_space(s.at(0), driveTotal, driveFree);
			allSpace += driveTotal;
			freeSpace += driveFree;

		}
		p += (_tcslen(p) + 1);

	}

	if (allSpace)
	{
		float ret = (float)(allSpace - freeSpace) / allSpace;
		return ret;
	}
	else
	{
		return 0.0;
	}

}


void GetSysInfo(void* param)
{
	float cpu = 0;
	float memory = 0;
	float disk = 0;
	float network = 0;

	unsigned long send,recv;

	SysInfo* info = (SysInfo*)param;


	while (info->m_run_flag)
	{
		//if (info->m_message_callback)
		{
			info->m_sys_info.cpu = QMCY_GetCPU();
			info->m_sys_info.memory = QMCY_GetMemory();
			info->m_sys_info.disk = QMCY_GetDisk();

			//info->m_message_callback(cpu, memory, disk, network);
		}
		Sleep(1000);
	}
}



SysInfo::SysInfo()
{
}

SysInfo::~SysInfo()
{

}


bool SysInfo::Start(MessageCallback cb)
{
	m_run_flag = true;
	if (!m_message_callback)
	{
		m_message_callback = cb;
	}

	if (!m_thread)
	{
		m_thread = new thread(GetSysInfo, this);
	}


	if (!m_sys_thread)
	{
		m_sys_thread = new thread(getResourceCounter, this);
	}

	return true;
}

void  SysInfo::Stop()
{
	m_run_flag = false;
	if (m_thread)
	{
		m_thread->join();
		delete m_thread;
	}

	if (m_sys_thread)
	{
		m_sys_thread->join();
		delete m_sys_thread;
	}

}


SYSINFO *SysInfo::GetInfo()
{
	return &m_sys_info;
}

调用部分:

 

vs2022 可以直接运行 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

QMCY_jason

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值