windows下的获取当前进程使用资源信息
程序员文章站
2022-05-25 23:47:33
...
在一些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;
}
推荐阅读
-
python使用wmi模块获取windows下硬盘信息的方法
-
python使用wmi模块获取windows下硬盘信息的方法
-
windows和linux下使用命令查找端口对应的进程pid并杀死进程
-
windows下的获取当前进程使用资源信息
-
python使用wmi模块获取windows下的系统信息监控系统
-
python使用wmi模块获取windows下的系统信息 监控系统
-
http - php的curl如何使用head协议来获取资源的大小等信息
-
http - php的curl如何使用head协议来获取资源的大小等信息
-
使用python编写脚本获取手机当前应用apk的信息
-
使用python编写脚本获取手机当前应用apk的信息