C/C++应用--Window下获取硬件信息(CPU, 硬盘,网卡等)
一、头文件如下:
#include <Windows.h> #include <string> #include <iostream> #include <winnt.h> #include <tchar.h> #include <IPHlpApi.h> #pragma comment(lib,"ws2_32.lib") #pragma comment(lib,"Advapi32.lib") #pragma comment(lib, "Iphlpapi.lib") using namespace std; // ***** global macros ***** // #define GBYTES 1073741824 #define MBYTES 1048576 #define KBYTES 1024 #define DKBYTES 1024.0 class CSysInfo { public: CSysInfo(); ~CSysInfo(); public: const std::string GetOSVersion(); void SafeGetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo); const std::string GetCPUInfo(); const std::string GetMemoryStatus(); void GetNetCardAndIPInfo(std::string &adapter_info, std::string &MAC_address, std::string &IP); const std::string GetComputerUserName(); BOOL GetHardDiskInfo(LPTSTR pModelNo, LPTSTR pSerialNo); void ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf); };
二、cpp如下:
#include "SysInfo.h" CSysInfo::CSysInfo() { } CSysInfo::~CSysInfo() { } const std::string CSysInfo::GetOSVersion() { std::string os_version(""); SYSTEM_INFO system_info; memset(&system_info, 0, sizeof(SYSTEM_INFO)); GetSystemInfo(&system_info); OSVERSIONINFOEX os; os.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); if (GetVersionEx((OSVERSIONINFO *)&os)) { switch (os.dwMajorVersion) { case 4: //1996年7月发布 switch (os.dwMinorVersion) { case 0: if (os.dwPlatformId == VER_PLATFORM_WIN32_NT) os_version = "Microsoft Windows NT 4.0 "; else if (os.dwPlatformId == VER_PLATFORM_WIN32_WINDOWS) os_version = "Microsoft Windows 95 "; break; case 10: os_version = "Microsoft Windows 98 "; break; case 90: os_version = "Microsoft Windows Me "; break; } break; case 5: switch (os.dwMinorVersion) { //1999年12月发布 case 0: os_version = "Microsoft Windows 2000 "; if (os.wSuiteMask == VER_SUITE_ENTERPRISE) os_version.append("Advanced Server "); break; //2001年8月发布 case 1: os_version = "Microsoft Windows XP "; if (os.wSuiteMask == VER_SUITE_EMBEDDEDNT) os_version.append("Embedded "); else if (os.wSuiteMask == VER_SUITE_PERSONAL) os_version.append("Home Edition "); else os_version.append("Professional "); break; case 2: if (os.wProductType == VER_NT_WORKSTATION && system_info.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64) os_version = "Microsoft Windows XP Professional x64 Edition "; if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_BLADE) os_version = "Microsoft Windows Server 2003 Web Edition "; else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_COMPUTE_SERVER) os_version = ("Microsoft Windows Server 2003 Compute Cluster Edition "); else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_STORAGE_SERVER) os_version = ("Microsoft Windows Server 2003 Storage Server "); else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_DATACENTER) os_version = ("Microsoft Windows Server 2003 Datacenter Edition "); else if (GetSystemMetrics(SM_SERVERR2) == 0 && os.wSuiteMask == VER_SUITE_ENTERPRISE) os_version = ("Microsoft Windows Server 2003 Enterprise Edition "); else if (GetSystemMetrics(SM_SERVERR2) != 0 && os.wSuiteMask == VER_SUITE_STORAGE_SERVER) os_version = ("Microsoft Windows Server 2003 R2 Storage Server "); break; } break; case 6: switch (os.dwMinorVersion) { case 0: if (os.wProductType == VER_NT_WORKSTATION) { os_version = "Microsoft Windows Vista "; if (os.wSuiteMask == VER_SUITE_PERSONAL) os_version.append("Home "); } else if (os.wProductType != VER_NT_WORKSTATION) { os_version = "Microsoft Windows Server 2008 "; if (os.wSuiteMask == VER_SUITE_DATACENTER) os_version.append("Datacenter Server "); else if (os.wSuiteMask == VER_SUITE_ENTERPRISE) os_version.append("Enterprise "); } break; case 1: if (os.wProductType == VER_NT_WORKSTATION) os_version = "Microsoft Windows 7 "; else os_version = "Microsoft Windows Server 2008 R2 "; break; } break; default: os_version = "? "; } } SYSTEM_INFO si; SafeGetNativeSystemInfo(&si); if (si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_AMD64 || si.wProcessorArchitecture == PROCESSOR_ARCHITECTURE_IA64) os_version.append("64bit"); else os_version.append("32bit"); return os_version; } void CSysInfo::SafeGetNativeSystemInfo(LPSYSTEM_INFO lpSystemInfo) { if (NULL == lpSystemInfo) return; typedef VOID(WINAPI *LPFN_GetNativeSystemInfo)(LPSYSTEM_INFO lpSystemInfo); LPFN_GetNativeSystemInfo nsInfo = (LPFN_GetNativeSystemInfo)GetProcAddress(GetModuleHandle(_T("kernel32")), "GetNativeSystemInfo");; if (NULL != nsInfo) { nsInfo(lpSystemInfo); } else { GetSystemInfo(lpSystemInfo); } } const std::string CSysInfo::GetCPUInfo() { std::string processor_name(""); std::string str_path = "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0"; HKEY key; if (::RegOpenKeyEx(HKEY_LOCAL_MACHINE, (LPCSTR)str_path.c_str(), 0, KEY_ALL_ACCESS, &key) == ERROR_SUCCESS) { char processor_value[256]; DWORD type = REG_SZ; DWORD value_size = sizeof(processor_value); if (::RegQueryValueEx(key, "ProcessorNameString", 0, &type, (LPBYTE)&processor_value, &value_size) == ERROR_SUCCESS) processor_name.append(processor_value, value_size); RegCloseKey(key); } return processor_name; } const std::string CSysInfo::GetMemoryStatus() { std::string memory_info(""); MEMORYSTATUSEX statusex; statusex.dwLength = sizeof(statusex); if (GlobalMemoryStatusEx(&statusex)) { unsigned long long total = 0, remain_total = 0, avl = 0, remain_avl = 0; double decimal_total = 0, decimal_avl = 0; remain_total = statusex.ullTotalPhys % GBYTES; total = statusex.ullTotalPhys / GBYTES; avl = statusex.ullAvailPhys / GBYTES; remain_avl = statusex.ullAvailPhys % GBYTES; if (remain_total > 0) decimal_total = (remain_total / MBYTES) / DKBYTES; if (remain_avl > 0) decimal_avl = (remain_avl / MBYTES) / DKBYTES; decimal_total += (double)total; decimal_avl += (double)avl; char buffer[MAX_PATH]; //sprintf_s(buffer, MAX_PATH, "%.2f GB (%.2f GB可用)", decimal_total, decimal_avl); sprintf_s(buffer, MAX_PATH, "%.2f GB", decimal_total); memory_info.append(buffer); } return memory_info; } void CSysInfo::GetNetCardAndIPInfo(std::string &adapter_info, std::string &MAC_address, std::string &IP) { PIP_ADAPTER_INFO pIp_adapter_info = new IP_ADAPTER_INFO(); unsigned long adapter_size = sizeof(IP_ADAPTER_INFO); int ret = GetAdaptersInfo(pIp_adapter_info, &adapter_size); if (ERROR_BUFFER_OVERFLOW == ret) { delete pIp_adapter_info; pIp_adapter_info = (PIP_ADAPTER_INFO)new BYTE[adapter_size]; ret = GetAdaptersInfo(pIp_adapter_info, &adapter_size); } if (ERROR_SUCCESS == ret) { while (pIp_adapter_info) { adapter_info.append("name: "); adapter_info.append(pIp_adapter_info->AdapterName); adapter_info.append("\ndescription: "); adapter_info.append(pIp_adapter_info->Description); adapter_info.append("\ntype: "); std::string card_type(""); switch (pIp_adapter_info->Type) { case MIB_IF_TYPE_OTHER: card_type = "other"; break; case MIB_IF_TYPE_ETHERNET: card_type = "ethernet"; break; case MIB_IF_TYPE_TOKENRING: card_type = "tokenring"; break; case MIB_IF_TYPE_FDDI: card_type = "fddi"; break; case MIB_IF_TYPE_PPP: card_type = "ppp"; break; case MIB_IF_TYPE_LOOPBACK: card_type = "loopback"; break; case MIB_IF_TYPE_SLIP: card_type = "slip"; break; default: break; } adapter_info.append(card_type); MAC_address.append("\nMACAddr: "); char buffer[MAX_PATH]; for (DWORD i = 0; i < pIp_adapter_info->AddressLength; i++) if (i < pIp_adapter_info->AddressLength - 1) { sprintf_s(buffer, MAX_PATH, "%02X", pIp_adapter_info->Address[i]); MAC_address.append(buffer); MAC_address.append("-"); } else { sprintf_s(buffer, MAX_PATH, "%02X", pIp_adapter_info->Address[i]); MAC_address.append(buffer); adapter_info.append("\n"); } IP_ADDR_STRING *pIp_addr_string = &(pIp_adapter_info->IpAddressList); do { IP.append("IPAddr:"); IP.append(pIp_addr_string->IpAddress.String);; IP.append("\nIpMask:"); IP.append(pIp_addr_string->IpMask.String); IP.append("\nGateway:"); IP.append(pIp_adapter_info->GatewayList.IpAddress.String); IP.append("\n"); pIp_addr_string = pIp_addr_string->Next; } while (pIp_addr_string); adapter_info.append("\n"); pIp_adapter_info = pIp_adapter_info->Next; } } if (pIp_adapter_info) { delete pIp_adapter_info; pIp_adapter_info = nullptr; } } const std::string CSysInfo::GetComputerUserName() { char szUsername[BUFSIZ]; DWORD bufCharCount = BUFSIZ; // Get and display the name of the computer. if (GetComputerName(szUsername, &bufCharCount)) { return szUsername; }else { return ""; } } BOOL CSysInfo::GetHardDiskInfo(LPTSTR pModelNo, LPTSTR pSerialNo) { //-1是因为 SENDCMDOUTPARAMS 的结尾是 BYTE bBuffer[1]; BYTE IdentifyResult[sizeof(SENDCMDOUTPARAMS) + IDENTIFY_BUFFER_SIZE - 1]; DWORD dwBytesReturned; GETVERSIONINPARAMS get_version; SENDCMDINPARAMS send_cmd = { 0 }; HANDLE hFile = CreateFile(_T("\\\\.\\PHYSICALDRIVE0"), GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, OPEN_EXISTING, 0, NULL); if (hFile == INVALID_HANDLE_VALUE) return FALSE; //get version DeviceIoControl(hFile, SMART_GET_VERSION, NULL, 0, &get_version, sizeof(get_version), &dwBytesReturned, NULL); //identify device send_cmd.irDriveRegs.bCommandReg = (get_version.bIDEDeviceMap & 0x10) ? ATAPI_ID_CMD : ID_CMD; DeviceIoControl(hFile, SMART_RCV_DRIVE_DATA, &send_cmd, sizeof(SENDCMDINPARAMS) - 1, IdentifyResult, sizeof(IdentifyResult), &dwBytesReturned, NULL); CloseHandle(hFile); //adjust the byte order PUSHORT pWords = (USHORT*)(((SENDCMDOUTPARAMS*)IdentifyResult)->bBuffer); ToLittleEndian(pWords, 27, 46, pModelNo); ToLittleEndian(pWords, 10, 19, pSerialNo); return true; } //把WORD数组调整字节序为little-endian,并滤除字符串结尾的空格。 void CSysInfo::ToLittleEndian(PUSHORT pWords, int nFirstIndex, int nLastIndex, LPTSTR pBuf) { int index; LPTSTR pDest = pBuf; for (index = nFirstIndex; index <= nLastIndex; ++index) { pDest[0] = pWords[index] >> 8; pDest[1] = pWords[index] & 0xFF; pDest += 2; } *pDest = 0; //trim space at the endof string; 0x20: _T(' ') --pDest; while (*pDest == 0x20) { *pDest = 0; --pDest; } }