Windows获取系统、进程CPU占用率、内存、磁盘、网卡

您所在的位置:网站首页 cmd查看内存大小命令 Windows获取系统、进程CPU占用率、内存、磁盘、网卡

Windows获取系统、进程CPU占用率、内存、磁盘、网卡

2023-09-14 17:54| 来源: 网络整理| 查看: 265

1、获取系统cpu:

使用WindowsAPI函数GetSystemTimes(),为获取当前使用率,通过执行两次的方式进行差值比较。在win7,win10上试验结果准确,具体用法参考下列代码:

//Windows程序获取cpu占用率 void GetCpuUsage_WIN(double* CPUResult) {     CPUResult[0] = 0;     CPUResult[1] = 0;     FILETIME ftIdle, ftKernel, ftUser;     //GetSystemTimes()获取系统CPU空闲时间、内核时间、用户时间     if (GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) {         m_fOldCPUIdleTime = FileTimeToDouble(&ftIdle);         m_fOldCPUKernelTime = FileTimeToDouble(&ftKernel);         m_fOldCPUUserTime = FileTimeToDouble(&ftUser);         //printf("自开机来的平均CPU占用率:%2.f%%", 100 * (1 - (m_fOldCPUIdleTime) / (m_fOldCPUKernelTime + m_fOldCPUUserTime)));         //printf("  %2.f%%\n", 100 * (m_fOldCPUIdleTime) / (m_fOldCPUKernelTime + m_fOldCPUUserTime));     }     Sleep(1000);     if (GetSystemTimes(&ftIdle, &ftKernel, &ftUser)) {         m_fOldCPUIdleTime = FileTimeToDouble(&ftIdle) - m_fOldCPUIdleTime;         m_fOldCPUKernelTime = FileTimeToDouble(&ftKernel) - m_fOldCPUKernelTime;         m_fOldCPUUserTime = FileTimeToDouble(&ftUser) - m_fOldCPUUserTime;     }     /*     *计算cpu占用率,注意内核时间中包含空闲时间,空闲时间为cpu空转时间     *运行时间=用户时间+内核时间-空闲时间     *间隔时间=用户时间+内核时间     *cpu占用率=运行时间/间隔时间,cpu闲置率=空闲时间/间隔时间     */     *CPUResult++ = 100 * (1 - (m_fOldCPUIdleTime) / (m_fOldCPUKernelTime + m_fOldCPUUserTime));     *CPUResult = (m_fOldCPUIdleTime) / (m_fOldCPUKernelTime + m_fOldCPUUserTime) * 100;     CPUResult--; }

win7比较如下:

2、获取进程CPU:

在最开始选择了使用GetProcessTimes()函数实现,发现其返回值中仅包含了内核时间以及用户时间,即使求取了差值也不清楚分母的大小,故在试验中使用GetSystemTimes()计算总时间。各位看官如可以采取更好的方式实现,可以在下发留言以供其他同学参考。

实现代码如下,win7、win10下与任务管理器结果一致,需注意,代码粗暴,自行优美:

//Windows执行cmd指令 bool Wincmd(char* cmd, char* result) {     char buffer[128];//缓冲区     FILE* pipe = _popen(cmd, "r");//_popen函数创建管道调用fork产生子进程,以执行cmd指令,这个进程需以_pclose关闭     if (!pipe) {         _pclose(pipe);         return false;     }     while (!feof(pipe)) {        //feof判断流、文件是否读完         if (fgets(buffer, 128, pipe)) {             strcat_s(result, 1024, buffer);             if (strlen(result) > 896) {                 break;             }         }     }     _pclose(pipe);     return true; } //判断进程是否存在 bool IsProExit(int ID) {     char str[128] = "tasklist /FI \"PID eq ";     char strPID[24] = { '\0' };     char* strbuf = NULL;     char* tmpstr = NULL;     _itoa_s(ID, strPID, 24, 10);     strcat_s(str, strPID);     strcat_s(str, "\"\n");     Wincmd(str, result);     if (!strstr(result, "PID")) {         return false;     }     //获取PID进程名称     strtok_s(result, "\n", &strbuf);     strtok_s(strbuf, "\n", &tmpstr);     strtok_s(tmpstr, " ", &strbuf);     strncpy_s(ProName, tmpstr, strlen(tmpstr));     memset(result, '\0', sizeof(result));     return true; } //获取进程cpu占用率 void GetCpuUsagPID_WIN(double* CPUResult) {     CPUResult[0] = 0;     CPUResult[1] = 0;     if (PID Shared == 0) dwMem += si.dwPageSize; } PIDMem[1] = dwMem / 1024; printf("dwMem:%u\n", dwMem/1024); } //free(pBuf); } //free(hprocess); } void GetMemUsagPID_WIN(int* PIDMem) { //先判断进程是否存在 if (!IsProExit(PID)) { PIDMem[0] = -1;//不存在则置为-1 return; } //获取总内存大小,MB GlobalMemoryStatusEx(&MemStat); PIDMem[0] = MemStat.ullTotalPhys / 1024 / 1024; //获取系统版本 OSVERSIONINFO osvi; memset(&osvi, 0, sizeof(OSVERSIONINFO)); osvi.dwOSVersionInfoSize = sizeof(OSVERSIONINFO); GetVersionExA(&osvi);//获取版本信息,需注意,windows8.1后 此函数被废弃,均返回6.2 //较旧版本 if (osvi.dwMajorVersion < 6.3){ GetMemVerOld(PIDMem); return; } //较新版本 //GetProcessMemoryInfo()获取PID进程内存占用/字节 HANDLE hprocess = OpenProcess(PROCESS_ALL_ACCESS, FALSE, PID); if (GetProcessMemoryInfo(hprocess, &pmc, sizeof(pmc))) { PIDMem[1] = pmc.WorkingSetSize / 1024; PIDMem[2] = pmc.PagefileUsage / 1024 ; } else { PIDMem[0] = -1; return; } }

此时结果就十分精确了,只是kb级别(任务管理器显示为kb)是无误差的。

 

5、CPU、磁盘、网卡:

查阅对应API属实花了不少时间,最后考虑使用WMI API函数实现,另附赠磁盘IO。具体代码如下:

void UseWmi(int caseNum){ //result code from COM calls HRESULT hr = 0; //COM interface pointers IWbemLocator *locator = NULL; IWbemServices *services = NULL; IEnumWbemClassObject *results = NULL; BSTR resource = SysAllocString(L"ROOT\\CIMV2"); BSTR language = SysAllocString(L"WQL"); /* Win32_PerfFormattedData_PerfDisk_LogicalDisk 代表逻辑磁盘性能数据对象,利用该对象可以获得磁盘的心能信息。Win32_PerfFormattedData_PerfDisk_LogicalDisk对象有以下一些主要的属性: Name: 磁盘名称 DiskTransfersPerSec:每秒磁盘传输次数。 DiskReadBytesPerSec:每秒从磁盘读取得数据量,单位为Byte。 DiskWriteBytesPerSec:每秒从磁盘读取得数据量,单位为Byte。 PercentFreeSpace:可用磁盘百分比。*/ BSTR query = NULL; //设定query switch (caseNum) { case 1: query = SysAllocString(L"Select * FROM Win32_PerfFormattedData_PerfOS_Processor"); break; case 3: query = SysAllocString(L"Select * FROM Win32_PerfFormattedData_PerfDisk_LogicalDisk"); break; case 30: query = SysAllocString(L"Select * FROM Win32_PerfFormattedData_PerfProc_Process"); break; case 4: query = SysAllocString(L"Select * FROM Win32_PerfFormattedData_Tcpip_NetworkInterface"); break; default: break; } //BSTR query = SysAllocString(L"Select PercentProcessorTime,IDProcess from Win32_PerfFormattedData_PerfProc_Process where IDProcess=992"); //initialize COM hr = CoInitializeEx(0, COINIT_MULTITHREADED); hr = CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_DEFAULT, RPC_C_IMP_LEVEL_IMPERSONATE, NULL, EOAC_NONE, NULL); // connect to WMI hr = CoCreateInstance(CLSID_WbemLocator, 0, CLSCTX_INPROC_SERVER, IID_IWbemLocator, (LPVOID *)&locator); hr = locator->ConnectServer(resource, NULL, NULL, NULL, 0, NULL, NULL, &services); // issue a WMI query hr = services->ExecQuery(language, query, WBEM_FLAG_BIDIRECTIONAL, NULL, &results); // list the query results if (results != NULL) { IWbemClassObject *result = NULL; ULONG returnedCount = 0; // enumerate the retrieved objects switch (caseNum) { case 1: while ((hr = results->Next(WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) { VARIANT name; VARIANT PercentIdleTime; // obtain the desired properties of the next result and print them out hr = result->Get(L"Name", 0, &name, 0, 0); //hr = result->Get(L"PercentIdleTime", 0, &PercentIdleTime, 0, 0); hr = result->Get(L"PercentProcessorTime", 0, &PercentIdleTime, 0, 0); BSTR tmp=PercentIdleTime.bstrVal; wprintf(L"## CPU:%s\t\tUse:%s%%\r\n", name.bstrVal, PercentIdleTime.bstrVal); if (EXCEL_status > 0) { } // release the current result object result->Release(); } break; case 3: DiskNum = 0; while ((hr = results->Next(WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) { // obtain the desired properties of the next result and print them out hr = result->Get(L"Name", 0, &name[DiskNum + DiskDt], 0, 0); hr = result->Get(L"DiskReadBytesPerSec", 0, &Readspeed[DiskNum + DiskDt], 0, 0); hr = result->Get(L"DiskWriteBytesPerSec", 0, &Writespeed[DiskNum + DiskDt], 0, 0); //wprintf(L"## DISK:%s\t\tReadSpeed:%d Bytes/s\t\tWriteSpeed:%d Byte/s,\r\n", name[DiskNum + DiskDt].bstrVal, Readspeed[DiskNum + DiskDt].intVal, Writespeed[DiskNum + DiskDt].intVal); // release the current result object result->Release(); DiskNum++; } break; case 30: while ((hr = results->Next(WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) { VARIANT name; char tmpID[256] = { '\0' }; // obtain the desired properties of the next result and print them out hr = result->Get(L"IDProcess", 0, &name, 0, 0); if (name.intVal == PID){ hr = result->Get(L"IODataBytesPersec", 0, &IODataBytesPersec, 0, 0); hr = result->Get(L"IOReadBytesPersec", 0, &IOReadBytesPersec, 0, 0); hr = result->Get(L"IOWriteBytesPersec", 0, &IOWriteBytesPersec, 0, 0); //wprintf(L"## PID:%d\tTotalIOSpeed:%d Bytes/s\tReadIOSpeed:%d Byte/s,\tWriteIOSpeed:%d Byte/s,\r\n", PID, IODataBytesPersec.intVal, IOReadBytesPersec.intVal, IOWriteBytesPersec.intVal); // release the current result object } result->Release(); } break; case 4: DiskNum = 0;//此处指代网卡数量,少定义变量,同样的还有DiskDt while ((hr = results->Next(WBEM_INFINITE, 1, &result, &returnedCount)) == S_OK) { //VARIANT name; // obtain the desired properties of the next result and print them out hr = result->Get(L"Name", 0, &name[DiskNum+DiskDt], 0, 0); hr = result->Get(L"BytesReceivedPersec", 0, &BytesReceivedPersec[DiskNum + DiskDt], 0, 0); hr = result->Get(L"BytesSentPersec", 0, &BytesSentPersec[DiskNum + DiskDt], 0, 0); hr = result->Get(L"BytesTotalPersec", 0, &BytesTotalPersec[DiskNum + DiskDt], 0, 0); //wprintf(L"## NETCARD:%s\n\tReceiveSpeed:%d Bytes/s\t\tSendSpeed:%d Bytes/s\t\tTotalSpeed:%d Bytes/s\r\n", name[DiskNum + DiskDt].bstrVal, BytesReceivedPersec[DiskNum + DiskDt].intVal, BytesSentPersec[DiskNum + DiskDt].intVal, BytesTotalPersec[DiskNum + DiskDt].intVal); // release the current result object result->Release(); DiskNum++; } break; default: break; } } // release WMI COM interfaces results->Release(); services->Release(); locator->Release(); // unwind everything else we've allocated CoUninitialize(); SysFreeString(query); SysFreeString(language); SysFreeString(resource); }

以上代码均可执行。

linux版本下均有对应指令可以获取,会方便许多,此处不贴代码。

整体可执行源码(还包含其他功能代码,跳过即可),稍后上传。



【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3