예전에 뭐땜시인지는 기억나지 않는데 CPU에 얼마나 여유가 있는지 확인하는 코드가 필요한적이 있었다.
그때 그 이유로 인터넷에서 여기저기 뒤쳐서 찾아놓은 샘플예제가 있었는데 지금 살펴보니 딱히 보기 좋은 상태가 아니라서(주석도 없고) 그냥 버리기엔 아깝고 해서 코드를 내 취향에 맞게 여기 정리해둠.
#include "SystemStatus.h" #include <string> #include <tchar.h> CSystemStatus::CSystemStatus(void) :m_hQuery(NULL),m_hCounterCPUTotal(NULL), m_CPUCoreCount(0), m_phCounterCPUCore(nullptr),m_NetAdaptorCount(0) { } CSystemStatus::~CSystemStatus(void) { } void CSystemStatus::Init() { PdhOpenQuery(NULL, 0, &m_hQuery); //CPU Total PdhAddCounter( m_hQuery, TEXT("\Processor(_Total)\% Processor Time"), 1, &m_hCounterCPUTotal ); // CPU core 정보 SYSTEM_INFO SystemInfo = { 0 }; GetSystemInfo(&SystemInfo); if (SystemInfo.dwNumberOfProcessors > 0){ m_CPUCoreCount = SystemInfo.dwNumberOfProcessors; m_phCounterCPUCore = new HCOUNTER[m_CPUCoreCount]; for (int cnt = 0; cnt < m_CPUCoreCount; cnt++){ TCHAR szFullCounterPath[1024] = { 0 }; wsprintf(szFullCounterPath, TEXT("\Processor(%d)\%% Processor Time"), cnt); PdhAddCounter(m_hQuery, szFullCounterPath, 1, &m_phCounterCPUCore[cnt]); } } // 네트워크 카드 DWORD pcchCounterListLength = 0, pcchInstanceListLength = 0 ; PdhEnumObjectItems( NULL, NULL, TEXT("Network Interface"), NULL, &pcchCounterListLength, NULL, &pcchInstanceListLength, PERF_DETAIL_WIZARD, 0 ); LPTSTR lpCounterList = new TCHAR[pcchCounterListLength]; m_lpNetAdaptorList = new TCHAR[pcchInstanceListLength]; if ( lpCounterList && m_lpNetAdaptorList ){ /*HKEY_LOCAL_MACHINESOFTWAREMicrosoftWindows NTCurrentVersionPerfliblangid */ /* Bytes Total/sec Packets/sec Packets Received/sec Packets Sent/sec Current Bandwidth Bytes Received/sec Packets Received Unicast/sec Packets Received Non-Unicast/sec Packets Received Discarded Packets Received Errors Packets Received Unknown Bytes Sent/sec Packets Sent Unicast/sec Packets Sent Non-Unicast/sec Packets Outbound Discarded Packets Outbound Errors Output Queue Length Offloaded Connections TCP Active RSC Connections TCP RSC Coalesced Packets/sec TCP RSC Exceptions/sec TCP RSC Average Packet Size */ PdhEnumObjectItems( NULL, NULL, TEXT("Network Interface"), lpCounterList, &pcchCounterListLength, m_lpNetAdaptorList, &pcchInstanceListLength, PERF_DETAIL_WIZARD, 0 ); TCHAR* pList = m_lpNetAdaptorList; m_NetAdaptorCount = 0; //어댑터 갯수 while (*pList) { m_NetAdaptorCount++; pList += (1 + _tcslen(pList)); } m_phCounterNetAdaptor = new HCOUNTER[m_NetAdaptorCount]; memset(m_phCounterNetAdaptor, 0, sizeof(HCOUNTER)*m_NetAdaptorCount); TCHAR* szInstanceName = m_lpNetAdaptorList; for (size_t cnt = 0; cnt < m_NetAdaptorCount; cnt++) { TCHAR szFullCounterPath[1024] = { 0 }; DWORD dwFullPathSize = 1024; PDH_COUNTER_PATH_ELEMENTS pcpe = { 0 }; pcpe.szObjectName = TEXT("Network Interface"); pcpe.szInstanceName = szInstanceName; pcpe.dwInstanceIndex = -1; pcpe.szCounterName = TEXT("Bytes Total/sec"); PdhMakeCounterPath(&pcpe, szFullCounterPath, &dwFullPathSize, 0); PdhAddCounter(m_hQuery, szFullCounterPath, 1, &m_phCounterNetAdaptor[cnt]); szInstanceName += (1 + _tcslen(szInstanceName)); } delete lpCounterList; } } void CSystemStatus::getCPUStatus(LONG &total, LONG* arrCore, size_t arrCoreSize) { PDH_FMT_COUNTERVALUE PFC_Value = { 0 }; PdhGetFormattedCounterValue(m_hCounterCPUTotal, PDH_FMT_LONG, NULL, &PFC_Value); total = PFC_Value.longValue; if (arrCore != nullptr && arrCoreSize > 0) { for (size_t c1 = 0; c1 < arrCoreSize; c1++){ PDH_FMT_COUNTERVALUE PFC_Value = { 0 }; PdhGetFormattedCounterValue(m_phCounterCPUCore[c1], PDH_FMT_LONG, NULL, &PFC_Value); arrCore[c1] = PFC_Value.longValue; } } } void CSystemStatus::getRAMStatus(int &availableMem, int &physicalMem) { //메모리값 MEMORYSTATUSEX MemoryStatus = {0}; MemoryStatus.dwLength = sizeof (MemoryStatus); ::GlobalMemoryStatusEx(&MemoryStatus); availableMem = (int)((MemoryStatus.ullTotalPhys - MemoryStatus.ullAvailPhys)/(1024*1024)); physicalMem = (int)((MemoryStatus.ullTotalPhys)/(1024*1024)); } void CSystemStatus::getNETStatus(LONG *adapTotalByte, size_t adaptorCount) { ////네트워크 PDH_FMT_COUNTERVALUE PFC_Value = { 0 }; for (int cnt = 0; cnt < adaptorCount; cnt++) { PdhGetFormattedCounterValue(m_phCounterNetAdaptor[cnt], PDH_FMT_LONG, NULL, &PFC_Value); adapTotalByte[cnt] = PFC_Value.longValue; } } void CSystemStatus::Update(){ // 카운트 갱신 PdhCollectQueryData( m_hQuery ); } void CSystemStatus::Terminate(){ PdhRemoveCounter(m_hCounterCPUTotal); for (int cnt = 0; cnt < m_CPUCoreCount; cnt++) PdhRemoveCounter(m_phCounterCPUCore[cnt]); delete(m_phCounterCPUCore); for (int cnt = 0; cnt < m_NetAdaptorCount; cnt++) PdhRemoveCounter(m_phCounterNetAdaptor[cnt]); delete[] m_phCounterNetAdaptor; delete[] m_lpNetAdaptorList; }
SystemStatus.cpp
#include <pdh.h> #include <pdhmsg.h> #include <Iphlpapi.h> #pragma comment(lib, "pdh.lib") #pragma comment(lib, "Iphlpapi.lib") class CSystemStatus{ private: HQUERY m_hQuery; size_t m_CPUCoreCount; HCOUNTER m_hCounterCPUTotal; HCOUNTER* m_phCounterCPUCore; size_t m_NetAdaptorCount; //어댑터 갯수 LPTSTR m_lpNetAdaptorList; //어댑터 이름 리스트 HCOUNTER* m_phCounterNetAdaptor; public: CSystemStatus(); ~CSystemStatus(void); void Init(); void Update(); void Terminate(); size_t getCPUCount() { return m_CPUCoreCount;} void getCPUStatus(LONG &total, LONG* arrCore, size_t arrCoreSize ); void getRAMStatus(int &availableMem, int &physicalMem); //단위:MB size_t getNetAdaptorCount() { return m_NetAdaptorCount; } const LPTSTR getNetAdatorList() { return m_lpNetAdaptorList;} void getNETStatus(LONG *adapTotalByte, size_t adaptorCount); };
SystemStatus.h
간단하게 설명하면 프로그램 실행시 Init(); 한번 실행해주고 프로그램 종료시에 Terminate(); 실행해주면 된다. 그리고 값 가져오기 전에 Update(); 한번 실행해주고 필요한 값 가져오면 됨.
다른것들에 대한걸 가져오고 싶으면 저 PdhAddCounter() 함수에 대해 여기저기 검색해보면 나옴.
//배터리 관련 정보 //https://msdn.microsoft.com/en-us/library/windows/desktop/aa373232(v=vs.85).aspx SYSTEM_POWER_STATUS power_status = { 0 }; if (GetSystemPowerStatus(&power_status)) { if (power_status.BatteryFlag != 128) { //128 == No system battery if (power_status.ACLineStatus == 1) tmpLog.Format(TEXT("전원 연결중rn")); else tmpLog.Format(TEXT("배터리 사용중rn")); m_strEditOutput += tmpLog; tmpLog.Format(TEXT("배터리 충전률: %d%%rn"), power_status.BatteryLifePercent); m_strEditOutput += tmpLog; if (power_status.BatteryLifeTime != -1){ int min = power_status.BatteryLifeTime / 60; if (min > 60) tmpLog.Format(TEXT("남은시간: %d시간 %d분rn"), min / 60, min % 60); else tmpLog.Format(TEXT("남은시간: %d분rn"), min); } else tmpLog.Format(TEXT("남은시간 계산중...rn")); m_strEditOutput += tmpLog; } else { tmpLog.Format(TEXT("No Batteryrn")); m_strEditOutput += tmpLog; } }
배터리 관련 정보 구하는 코드
//하드디스크 DWORD dwDrive = GetLogicalDrives(); DWORD dwDriveCh = 0x0001; TCHAR DriveText[3] = { 0 }; for (TCHAR Drive = 'A'; Drive <= 'Z'; Drive++){ wsprintf(DriveText, TEXT("%C:"), Drive); UINT type = GetDriveType(DriveText); if ((dwDrive & dwDriveCh) && (type == DRIVE_REMOVABLE || type == DRIVE_FIXED || type == DRIVE_RAMDISK)){ // 하드용량 ULARGE_INTEGER i64FreeBytesToCaller = { 0 }, i64TotalBytes = { 0 }, i64FreeBytes = { 0 }; BOOL bRsult = GetDiskFreeSpaceEx(DriveText, (PULARGE_INTEGER)&i64FreeBytesToCaller, (PULARGE_INTEGER)&i64TotalBytes, (PULARGE_INTEGER)&i64FreeBytes); if (bRsult){ float ra = 1.0f - (float)(int)(i64FreeBytes.QuadPart >> 20) / (float)(int)(i64TotalBytes.QuadPart >> 20); tmpLog.Format(TEXT("%c: %I64d MB / %I64d MB(%d%%)rn"), Drive, i64FreeBytes.QuadPart >> 20, i64TotalBytes.QuadPart >> 20, (int)(ra * 100)); m_strEditOutput += tmpLog; } } dwDriveCh <<= 1; }
하드디스크 정보 구하는 코드
답글 남기기