windows下的获取当前进程使用资源信息

在一些windows程序中需求需要分析当前程序运行的状态,那么就需要程序自己去捕获自己当前的所使用资源信息。这里上传一个封装好了的程序。

CPU_MEMusage.h

#include <Windows.h>   
#include <stdint.h>
#include <tlhelp32.h>
#include <psapi.h>
#include <string>
#include <crtdbg.h> 

#pragma warning(disable:4996)
//原理:调用GetProcessTimes(),并与上次调用得到的结果相减,即得到某段时间内CPU的使用时间  
//C++ 获取特定进程规定CPU使用率  原文:http://blog.csdn.net/liuqx97bb/article/details/52058657  
class CPU_MEMusage {
private:
	typedef long long          int64_t;
	typedef unsigned long long uint64_t;
	HANDLE _hProcess;
	int _processor;    //cpu数量    
	int64_t _last_time;         //上一次的时间    
	int64_t _last_system_time;


	// 时间转换    
	uint64_t file_time_2_utc(const FILETIME* ftime);

	// 获得CPU的核数    
	int get_processor_number();

	//初始化  
	void init()
	{
		_last_system_time = 0;
		_last_time = 0;
		_hProcess = 0;
	}

	//关闭进程句柄  
	void clear()
	{
		if (_hProcess) {
			CloseHandle(_hProcess);
			_hProcess = 0;
		}
	}

public:
	DWORD  ProcessID;//线程pid

	CPU_MEMusage(const char* pName) {
		ProcessID = GetProcessIDByName(pName);
		_processor = get_processor_number();
		setpid(ProcessID);
	}
	CPU_MEMusage() { init(); _processor = get_processor_number(); }
	~CPU_MEMusage() { clear(); }

	//获取进行Pid号
	DWORD GetProcessIDByName(const char* pName);

	//返回值为进程句柄,可判断OpenProcess是否成功  
	HANDLE setpid(DWORD ProcessID) {
		clear();    //如果之前监视过另一个进程,就先关闭它的句柄  
		init();
		return _hProcess = OpenProcess(PROCESS_QUERY_LIMITED_INFORMATION, false, ProcessID);
	}

	//-1 即为失败或进程已退出; 如果成功,首次调用会返回-2(中途用setpid更改了PID后首次调用也会返回-2)  
	float get_cpu_usage();

	//获取 WIN 硬盘使用情况  
	int getWin_DiskUsage(std::string &info);

	//获取内存使用情况
	int get_memory_usage(uint64_t* mem, uint64_t* vmem)
	{
		PROCESS_MEMORY_COUNTERS pmc;
		if (GetProcessMemoryInfo(_hProcess, &pmc, sizeof(pmc)))
		{
			if (mem) *mem = pmc.WorkingSetSize/1024;
			if (vmem) *vmem = pmc.PagefileUsage/1024;
			return 0;
		}
		return -1;
	};

	int get_io_bytes(uint64_t* read_bytes, uint64_t* write_bytes)
	{
		IO_COUNTERS io_counter;
		if (GetProcessIoCounters(_hProcess, &io_counter))
		{
			if (read_bytes) *read_bytes = io_counter.ReadTransferCount;
			if (write_bytes) *write_bytes = io_counter.WriteTransferCount;
			return 0;
		}
		return -1;
	};

	std::string intToString(int v)
	{
		char buf[32] = { 0 };
		_snprintf(buf, sizeof(buf), "%u", v);

		std::string str = buf;
		return str;
	};
};

CPU_MEMusage.cpp

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

using namespace std;
float CPU_MEMusage::get_cpu_usage()
{

	FILETIME now;
	FILETIME creation_time;
	FILETIME exit_time;
	FILETIME kernel_time;
	FILETIME user_time;
	int64_t system_time;
	int64_t time;
	int64_t system_time_delta;
	int64_t time_delta;

	DWORD exitcode;

	float cpu = -1;

	if (!_hProcess) return -1;

	GetSystemTimeAsFileTime(&now);

	//判断进程是否已经退出  
	GetExitCodeProcess(_hProcess, &exitcode);
	if (exitcode != STILL_ACTIVE) {
		clear();
		return -1;
	}

	//计算占用CPU的百分比  
	if (!GetProcessTimes(_hProcess, &creation_time, &exit_time, &kernel_time, &user_time))
	{
		clear();
		return -1;
	}
	system_time = (file_time_2_utc(&kernel_time) + file_time_2_utc(&user_time))
		/ _processor;
	time = file_time_2_utc(&now);

	//判断是否为首次计算  
	if ((_last_system_time == 0) || (_last_time == 0))
	{
		_last_system_time = system_time;
		_last_time = time;
		return 0;
	}

	system_time_delta = system_time - _last_system_time;
	time_delta = time - _last_time;

	if (time_delta == 0) {
		return -1;
	}

	cpu = (float)system_time_delta * 100 / (float)time_delta;
	_last_system_time = system_time;
	_last_time = time;
	return cpu;
}

CPU_MEMusage::uint64_t CPU_MEMusage::file_time_2_utc(const FILETIME* ftime)
{
	LARGE_INTEGER li;

	li.LowPart = ftime->dwLowDateTime;
	li.HighPart = ftime->dwHighDateTime;
	return li.QuadPart;
}

int CPU_MEMusage::get_processor_number()
{
	SYSTEM_INFO info;
	GetSystemInfo(&info);
	return info.dwNumberOfProcessors;
}

//获取 WIN 硬盘使用情况  
int CPU_MEMusage::getWin_DiskUsage(string & info)
{
	int DiskCount = 0;
	DWORD DiskInfo = GetLogicalDrives();
	//利用GetLogicalDrives()函数可以获取系统中逻辑驱动器的数量,函数返回的是一个32位无符号整型数据。    
	while (DiskInfo)//通过循环操作查看每一位数据是否为1,如果为1则磁盘为真,如果为0则磁盘不存在。    
	{
		if (DiskInfo & 1)//通过位运算的逻辑与操作,判断是否为1    
		{
			++DiskCount;
		}
		DiskInfo = DiskInfo >> 1;//通过位运算的右移操作保证每循环一次所检查的位置向右移动一位。       
	}
	info = "Logical Disk Number:" + intToString(DiskCount) + "\n";

	//-----------------------------------------------------------------------------------------     
	char DStr[1024] = { 0 };
	GetLogicalDriveStrings(1024, (LPTSTR)DStr);
	//通过GetLogicalDriveStrings将字符串信息复制到堆区数组中,其中保存了所有驱动器的信息。    

	int DType;
	int si = 0;
	BOOL fResult;
	unsigned _int64 i64FreeBytesToCaller;
	unsigned _int64 i64TotalBytes;
	unsigned _int64 i64FreeBytes;

	for (int i = 0; i< DiskCount; ++i)//为了显示每个驱动器的状态,则通过循环输出实现,由于DStr内部保存的数据是A:\NULLB:\NULLC:\NULL,这样的信息,所以DSLength/4可以获得具体大循环范围    
	{
		char dir[16] = { 0 };
		memcpy(dir, (LPTSTR)DStr + (i * 4), 1);
		strcat(dir, ":");
		info += dir;
		DType = GetDriveType((LPTSTR)DStr + (i * 4));
		//GetDriveType函数,可以获取驱动器类型,参数为驱动器的根目录    
		if (DType == DRIVE_FIXED)
		{
			info += "硬盘:";
		}
		else if (DType == DRIVE_CDROM)
		{
			info += "光驱:";
		}
		else if (DType == DRIVE_REMOVABLE)
		{
			info += "可移动磁盘:";
		}
		else if (DType == DRIVE_REMOTE)
		{
			info += "网络磁盘:";
		}
		else if (DType == DRIVE_RAMDISK)
		{
			info += "虚拟RAM磁盘:";
		}
		else if (DType == DRIVE_UNKNOWN)
		{
			info += "未知设备:";
		}

		fResult = GetDiskFreeSpaceEx(
			(LPTSTR)DStr + i * 4,
			(PULARGE_INTEGER)&i64FreeBytesToCaller,
			(PULARGE_INTEGER)&i64TotalBytes,
			(PULARGE_INTEGER)&i64FreeBytes);
		//GetDiskFreeSpaceEx函数,可以获取驱动器磁盘的空间状态,函数返回的是个BOOL类型数据    
		if (fResult)//通过返回的BOOL数据判断驱动器是否在工作状态    
		{
			info += "totalspace(磁盘总容量):";
			info += intToString((float)i64TotalBytes / 1024 / 1024);
			info += " MB        ";
			info += "freespace(磁盘剩余空间):";
			info += intToString((float)i64FreeBytesToCaller / 1024 / 1024);
			info += " MB\n";    
		}
		else
		{
			cout << " 设备未准备好";
		}
	}

	return 0;
}

DWORD CPU_MEMusage::GetProcessIDByName(const char* pName)
{
	HANDLE hSnapshot = CreateToolhelp32Snapshot(TH32CS_SNAPPROCESS, 0);
	if (INVALID_HANDLE_VALUE == hSnapshot) {
		return NULL;
	}
	PROCESSENTRY32 pe = { sizeof(pe) };
	int equal = -1;
	for (BOOL ret = Process32First(hSnapshot, &pe); ret; ret = Process32Next(hSnapshot, &pe)) {
		int bufSize = WideCharToMultiByte(CP_ACP, NULL, pe.szExeFile, -1, NULL, 0, NULL, FALSE);
		//std::cout << bufSize << std::endl;
		char *sp = new char[bufSize];
		WideCharToMultiByte(CP_ACP, NULL, pe.szExeFile, -1, sp, bufSize, NULL, FALSE);
		//std::cout << sp << std::endl;
		equal = strcmp(sp, pName);
		delete[] sp;
		if (!equal)
		{
			CloseHandle(hSnapshot);
			return pe.th32ProcessID;
		}
	}
	CloseHandle(hSnapshot);
	return 0;
};

使用示例程序:

main.cpp

#define CRTDBG_MAP_ALLOC
#include "CPU_MEMusage.h"  
#include <stdio.h>
#include <string.h>
#include <iostream>

int main()
{
	CPU_MEMusage usg("systeminfo.exe");
	unsigned int a = 0x10;
	unsigned int b = 0x02;
	unsigned int c = a | b;
	std::cout << c << std::endl;
	while (1)
	//for (int i=0;i<100;i++)
	{
		std::string disk;
		uint64_t mem = 0, vmem = 0, r = 0, w = 0;

		float cpu = usg.get_cpu_usage();
		usg.get_memory_usage(&mem, &vmem);
		usg.get_io_bytes(&r, &w);
		usg.getWin_DiskUsage(disk);
		printf("systeminfo.exe:is pid=%d\ncpu使用率:%.2f%%\n",usg.ProcessID, cpu);
		printf("内存使用: %d KB\n", mem);
		printf("虚拟内存使用: %d KB\n", vmem);
		printf("总共读: %u 字节\n", r);
		printf("总共写: %u 字节\n", w);
		std::cout << disk << std::endl;
		Sleep(500);
		
	}
	_CrtDumpMemoryLeaks();
	return 0;
}

猜你喜欢

转载自blog.csdn.net/liyu123__/article/details/81075906