WIN10 API打印CPU占用率

环境:win10+VS2017

网上找了几个demo发现CPU占用率不准确,跟任务管理器不一样。最后参考github项目GitHub - zhongyang219/TrafficMonitor: 这是一个用于显示当前网速、CPU及内存利用率的桌面悬浮窗软件,并支持任务栏显示,支持更换皮肤。,能过获取比较准确的CPU占用率。

注意要一秒获取一次CPU占用率,时间太短就不准确了。

WinVersionHelper.h

#pragma once

#define g_winVerHelper CWinVersionHelper::instance()

class CWinVersionHelper
{
public:
    static CWinVersionHelper& instance();

	CWinVersionHelper();
	~CWinVersionHelper();

	bool IsWindows10FallCreatorOrLater() const;		// 判断当前Windows版本是否为Win10秋季创意者更新或更新的版本
	bool IsWindows7() const;					    // 判断Windows版本是否为Windows7
	bool IsWindows8Or8point1() const;			    // 判断Windows版本是否为Windows8或Windows8.1
    bool IsWindows8OrLater() const;
    bool IsWindows10OrLater() const;

	int GetMajorVersion() const { return m_major_version; }
	int GetMinorVersion() const { return m_minor_version; }
	int GetBuildNumber() const { return m_build_number; }
protected:
	int m_major_version{};
	int m_minor_version{};
	int m_build_number{};
};

WinVersionHelper.cpp

#include "WinVersionHelper.h"
#include <Windows.h>


CWinVersionHelper& CWinVersionHelper::instance()
{
    static CWinVersionHelper s_instance;
    return s_instance;
}

CWinVersionHelper::CWinVersionHelper()
{
	DWORD dwMajorVer{}, dwMinorVer{}, dwBuildNumber{};
	HMODULE hModNtdll{};
	if (hModNtdll = ::LoadLibraryW(L"ntdll.dll"))
	{
		typedef void (WINAPI *pfRTLGETNTVERSIONNUMBERS)(DWORD*, DWORD*, DWORD*);
		pfRTLGETNTVERSIONNUMBERS pfRtlGetNtVersionNumbers;
		pfRtlGetNtVersionNumbers = (pfRTLGETNTVERSIONNUMBERS)::GetProcAddress(hModNtdll, "RtlGetNtVersionNumbers");
		if (pfRtlGetNtVersionNumbers)
		{
			pfRtlGetNtVersionNumbers(&dwMajorVer, &dwMinorVer, &dwBuildNumber);
			dwBuildNumber &= 0x0ffff;
		}
		::FreeLibrary(hModNtdll);
		hModNtdll = NULL;
	}
	m_major_version = dwMajorVer;
	m_minor_version = dwMinorVer;
	m_build_number = dwBuildNumber;
}


CWinVersionHelper::~CWinVersionHelper()
{
}

bool CWinVersionHelper::IsWindows10FallCreatorOrLater() const
{
	if (m_major_version > 10)
		return true;
	else if (m_major_version == 10 && m_minor_version > 0)
		return true;
	else if (m_major_version == 10 && m_minor_version == 0 && m_build_number >= 16299)
		return true;
	else return false;
}

bool CWinVersionHelper::IsWindows7() const
{
	return (m_major_version == 6 && m_minor_version == 1);
}

bool CWinVersionHelper::IsWindows8Or8point1() const
{
	return (m_major_version == 6 && m_minor_version > 1);
}

bool CWinVersionHelper::IsWindows8OrLater() const
{
    if (m_major_version > 6)
        return true;
    else if (m_major_version == 6 && m_minor_version >= 2)
        return true;
    else return false;
}

bool CWinVersionHelper::IsWindows10OrLater() const
{
    return m_major_version >= 10;
}

CCPUUsage.h:

#pragma once
#include <Pdh.h>
#include <PdhMsg.h>
#pragma comment(lib,"pdh.lib")

class CCPUUsage
{
public:
	CCPUUsage()
	{}

	~CCPUUsage()
	{}

	void SetUseCPUTimes(bool use_get_system_times);		//设置获取CPU利用率的方式,是通过GetSystemTimes还是Pdh
	int GetCPUUsage();

private:
	//int GetCPUUsageByGetSystemTimes();
	int GetCPUUsageByPdh();

private:
	bool m_use_get_system_times{ true };		//是否使用GetSysTime这个API来获取CPU利用率

	PDH_RAW_COUNTER m_last_rawData;//保存计算CPU使用率的上一次数据
	bool m_first_get_CPU_utility{ true };

	FILETIME m_preidleTime{};
	FILETIME m_prekernelTime{};
	FILETIME m_preuserTime{};

};

CCPUUsage.cpp:

#if 1
#include "CPUUsage.h"
#include "WinVersionHelper.h"
#include <iostream>

using namespace std;


void CCPUUsage::SetUseCPUTimes(bool use_get_system_times)
{
	if (m_use_get_system_times != use_get_system_times)
	{
		m_use_get_system_times = use_get_system_times;
		m_first_get_CPU_utility = true;
	}
}

int CCPUUsage::GetCPUUsage()
{
	//if (m_use_get_system_times)
	//	return GetCPUUsageByGetSystemTimes();
	//else
		return GetCPUUsageByPdh();
}

#if 0
int CCPUUsage::GetCPUUsageByGetSystemTimes()
{
	int cpu_usage{};
	FILETIME idleTime;
	FILETIME kernelTime;
	FILETIME userTime;
	GetSystemTimes(&idleTime, &kernelTime, &userTime);

	__int64 idle = CCommon::CompareFileTime2(m_preidleTime, idleTime);
	__int64 kernel = CCommon::CompareFileTime2(m_prekernelTime, kernelTime);
	__int64 user = CCommon::CompareFileTime2(m_preuserTime, userTime);

	if (kernel + user == 0)
	{
		cpu_usage = 0;
	}
	else
	{
		//(总的时间-空闲时间)/总的时间=占用cpu的时间就是使用率
		cpu_usage = static_cast<int>(abs((kernel + user - idle) * 100 / (kernel + user)));
	}
	m_preidleTime = idleTime;
	m_prekernelTime = kernelTime;
	m_preuserTime = userTime;

	return cpu_usage;
}
#endif

#include <iostream>
using namespace std;

int CCPUUsage::GetCPUUsageByPdh()
{
	int cpu_usage{};
	HQUERY hQuery;
	HCOUNTER hCounter;
	DWORD counterType;
	PDH_RAW_COUNTER rawData;

	PdhOpenQuery(NULL, 0, &hQuery);//开始查询
	const wchar_t* query_str{};
	if (g_winVerHelper.GetMajorVersion() >= 10)
		query_str = L"\\Processor Information(_Total)\\% Processor Utility";
	else
		query_str = L"\\Processor Information(_Total)\\% Processor Time";
	PdhAddCounter(hQuery, query_str, NULL, &hCounter);
	PdhCollectQueryData(hQuery);
	PdhGetRawCounterValue(hCounter, &counterType, &rawData);

	if (m_first_get_CPU_utility) {//需要获得两次数据才能计算CPU使用率
		cpu_usage = 0;
		m_first_get_CPU_utility = false;
	}
	else {
		PDH_FMT_COUNTERVALUE fmtValue;
		PdhCalculateCounterFromRawValue(hCounter, PDH_FMT_DOUBLE, &rawData, &m_last_rawData, &fmtValue);//计算使用率
		cpu_usage = fmtValue.doubleValue;//传出数据
		if (cpu_usage > 100)
			cpu_usage = 100;
	}
	m_last_rawData = rawData;//保存上一次数据
	PdhCloseQuery(hQuery);//关闭查询
	return cpu_usage;
}

#endif

main.cpp

#include "CPUUsage.h"
#include <iostream>

using namespace std;


int main() {
    CCPUUsage cpuUsage;
    cpuUsage.SetUseCPUTimes(false);
    while (1) {
        cout << cpuUsage.GetCPUUsage() << endl;
        Sleep(1000);
    }
}

要在 Node.js 中实现一个页面显示 CPU、内存和磁盘占用率的应用,我们可以采用前后端分离的方式,前端页面通过 AJAX 请求后端 API 获取数据,并将数据展示在页面上。 以下是一个简单的示例代码,实现了一个后端 API 和一个前端页面,可以显示 CPU、内存和磁盘占用率的信息。 后端 API: ``` const os = require('os') const express = require('express') const app = express() // 获取 CPU 使用率 app.get('/api/cpu', (req, res) => { const usage = process.cpuUsage() const totalUsage = usage.user + usage.system const percentage = (totalUsage / 1000 / 1000) * 100 res.json({ usage: percentage.toFixed(2) }) }) // 获取内存使用情况 app.get('/api/memory', (req, res) => { const total = os.totalmem() const free = os.freemem() const used = total - free const percentage = (used / total) * 100 res.json({ usage: percentage.toFixed(2) }) }) // 获取磁盘使用情况 app.get('/api/disk', (req, res) => { const disk = os.platform() === 'win32' ? 'C:' : '/' const diskInfo = os.fsSpaceSync(disk) const total = diskInfo.size const free = diskInfo.free const used = total - free const percentage = (used / total) * 100 res.json({ usage: percentage.toFixed(2) }) }) app.listen(3000, () => { console.log('Server is running on port 3000') }) ``` 前端页面: ```html <!DOCTYPE html> <html> <head> <meta charset="UTF-8"> <title>System Monitor</title> </head> <body> <h1>System Monitor</h1> <p>CPU Usage: <span id="cpu-usage"></span>%</p> <p>Memory Usage: <span id="memory-usage"></span>%</p> <p>Disk Usage: <span id="disk-usage"></span>%</p> <script> function updateData() { // 更新 CPU 使用率 fetch('/api/cpu') .then(res => res.json()) .then(data => { document.getElementById('cpu-usage').textContent = data.usage }) // 更新内存使用情况 fetch('/api/memory') .then(res => res.json()) .then(data => { document.getElementById('memory-usage').textContent = data.usage }) // 更新磁盘使用情况 fetch('/api/disk') .then(res => res.json()) .then(data => { document.getElementById('disk-usage').textContent = data.usage }) } setInterval(updateData, 1000) </script> </body> </html> ``` 在上面的示例中,后端 API 通过 Express 框架实现,分别提供了 `/api/cpu`、`/api/memory` 和 `/api/disk` 三个接口,用于获取 CPU、内存和磁盘占用率的信息。前端页面通过 AJAX 请求这些接口,获取到数据后将其展示在页面上。页面的 `updateData()` 函数会每秒钟更新一次数据,并展示在页面上。
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值