有时候需要在工程里面获取一些系统或者硬件的信息,比如系统版本,cpu,内存,显卡,硬盘,网络等,作为后续软件功能判断的依据,甚至参与性能算法自适应建模
Windows
操作系统和内存信息在windows下通过系统的API来获取,CPU信息则需要需要通过底层CPUID指令取得
代码:
#include <iostream> #include <string> #include <string.h> #include <winsock2.h> // include must before window.h #include <iphlpapi.h> #include <windows.h> #pragma comment(lib, "iphlpapi.lib") #pragma warning(disable: 4996) // avoid GetVersionEx to be warned // ***** global macros ***** // static const int kMaxInfoBuffer = 256; #define GBYTES 1073741824 #define MBYTES 1048576 #define KBYTES 1024 #define DKBYTES 1024.0 // ---- get os info ---- // void getOsInfo() { // get os name according to version number OSVERSIONINFO osver = { sizeof(OSVERSIONINFO) }; GetVersionEx(&osver); std::string os_name; if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 0) os_name = "Windows 2000"; else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 1) os_name = "Windows XP"; else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 0) os_name = "Windows 2003"; else if (osver.dwMajorVersion == 5 && osver.dwMinorVersion == 2) os_name = "windows vista"; else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 1) os_name = "windows 7"; else if (osver.dwMajorVersion == 6 && osver.dwMinorVersion == 2) os_name = "windows 10"; std::cout << "os name: " << os_name << std::endl; std::cout << "os version: " << osver.dwMajorVersion << '.' << osver.dwMinorVersion << std::endl; } // ---- get cpu info ---- // #ifdef _WIN64 // method 2: usde winapi, works for x86 and x64 #include <intrin.h> void getCpuInfo() { int cpuInfo[4] = {-1}; char cpu_manufacture[32] = { 0 }; char cpu_type[32] = { 0 }; char cpu_freq[32] = { 0 }; __cpuid(cpuInfo, 0x80000002); memcpy(cpu_manufacture, cpuInfo, sizeof(cpuInfo)); __cpuid(cpuInfo, 0x80000003); memcpy(cpu_type, cpuInfo, sizeof(cpuInfo)); __cpuid(cpuInfo, 0x80000004); memcpy(cpu_freq, cpuInfo, sizeof(cpuInfo)); std::cout << "CPU manufacture: " << cpu_manufacture << std::endl; std::cout << "CPU type: " << cpu_type << std::endl; std::cout << "CPU main frequency: " << cpu_freq << std::endl; } #else // mothed 1: this kind asm embedded in code only works in x86 build // save 4 register variables DWORD deax; DWORD debx; DWORD decx; DWORD dedx; // init cpu in assembly language void initCpu(DWORD veax) { __asm { mov eax, veax cpuid mov deax, eax mov debx, ebx mov decx, ecx mov dedx, edx } } long getCpuFreq() { int start, over; _asm { RDTSC mov start, eax } Sleep(50); _asm { RDTSC mov over, eax } return (over - start) / 50000; } std::string getManufactureID() { char manuID[25]; memset(manuID, 0, sizeof(manuID)); initCpu(0); memcpy(manuID + 0, &debx, 4); // copy to array memcpy(manuID + 4, &dedx, 4); memcpy(manuID + 8, &decx, 4); return manuID; } std::string getCpuType() { const DWORD id = 0x80000002; // start 0x80000002 end to 0x80000004 char cpuType[49]; memset(cpuType, 0, sizeof(cpuType)); for (DWORD t = 0; t < 3; t++) { initCpu(id + t); memcpy(cpuType + 16 * t + 0, &deax, 4); memcpy(cpuType + 16 * t + 4, &debx, 4); memcpy(cpuType + 16 * t + 8, &decx, 4); memcpy(cpuType + 16 * t + 12, &dedx, 4); } return cpuType; } void getCpuInfo() { std::cout << "CPU manufacture: " << getManufactureID() << std::endl; std::cout << "CPU type: " << getCpuType() << std::endl; std::cout << "CPU main frequency: " << getCpuFreq() << "MHz" << std::endl; } #endif // ---- get memory info ---- // void getMemoryInfo() { 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[kMaxInfoBuffer]; sprintf_s(buffer, kMaxInfoBuffer, "total %.2f GB (%.2f GB available)", decimal_total, decimal_avl); memory_info.append(buffer); } std::cout << memory_info << std::endl; } // ---- get harddisk info ---- // std::string execCmd(const char *cmd) { char buffer[128] = { 0 }; std::string result; FILE *pipe = _popen(cmd, "r"); if (!pipe) throw std::runtime_error("_popen() failed!"); while (!feof(pipe)) { if (fgets(buffer, 128, pipe) != NULL) result += buffer; } _pclose(pipe); return result; } void getHardDiskInfo() { std::string hd_seiral = execCmd("wmic path win32_physicalmedia get SerialNumber"); std::cout << "HardDisk Serial Number: " << hd_seiral << std::endl; } // ---- get network info ---- // void getNetworkInfo() { // PIP_ADAPTER_INFO struct contains network information PIP_ADAPTER_INFO pIpAdapterInfo = new IP_ADAPTER_INFO(); unsigned long adapter_size = sizeof(IP_ADAPTER_INFO); int ret = GetAdaptersInfo(pIpAdapterInfo, &adapter_size); if (ret == ERROR_BUFFER_OVERFLOW) { // overflow, use the output size to recreate the handler delete pIpAdapterInfo; pIpAdapterInfo = (PIP_ADAPTER_INFO)new BYTE[adapter_size]; ret = GetAdaptersInfo(pIpAdapterInfo, &adapter_size); } if (ret == ERROR_SUCCESS) { int card_index = 0; // may have many cards, it saved in linklist while (pIpAdapterInfo) { std::cout << "---- " << "NetworkCard " << ++card_index << " ----" << std::endl; std::cout << "Network Card Name: " << pIpAdapterInfo->AdapterName << std::endl; std::cout << "Network Card Description: " << pIpAdapterInfo->Description << std::endl; // get IP, one card may have many IPs PIP_ADDR_STRING pIpAddr = &(pIpAdapterInfo->IpAddressList); while (pIpAddr) { char local_ip[128] = { 0 }; strcpy(local_ip, pIpAddr->IpAddress.String); std::cout << "Local IP: " << local_ip << std::endl; pIpAddr = pIpAddr->Next; } char local_mac[128] = { 0 }; int char_index = 0; for (int i = 0; i < pIpAdapterInfo->AddressLength; i++) { char temp_str[10] = { 0 }; sprintf(temp_str, "%02X-", pIpAdapterInfo->Address[i]); // X for uppercase, x for lowercase strcpy(local_mac + char_index, temp_str); char_index += 3; } local_mac[17] = '\0'; // remove tail '-' std::cout << "Local Mac: " << local_mac << std::endl; // here just need the first card info break; // iterate next //pIpAdapterInfo = pIpAdapterInfo->Next; } } if (pIpAdapterInfo) delete pIpAdapterInfo; } int main(int argc, char *argv[]) { std::cout << "=== os information ===" << std::endl; getOsInfo(); std::cout << "=== cpu infomation ===" << std::endl; getCpuInfo(); std::cout << "=== memory information ===" << std::endl; getMemoryInfo(); std::cout << "=== harddisk information ===" << std::endl; getHardDiskInfo(); std::cout << "=== network information ===" << std::endl; getNetworkInfo(); system("pause"); return 0; }
=== os information ===
os name: windows 10
os version: 6.2
=== cpu infomation ===
CPU manufacture: GenuineIntel
CPU type: Intel(R) Core(TM) i7-8700 CPU @ 3.20GHz
CPU main frequency: 3231MHz
=== memory information ===
total 7.92 GB (4.00 GB available)
=== harddisk information ===
HardDisk Serial Number: SerialNumber
0100_0000_0000_0000.
W9A5EXTF
NA8QC8GM
=== network information ===
---- NetworkCard 1 ----
Network Card Name: {50C5A628-46B0-4009-9200-5CE1FD512B2B}
Network Card Description: Realtek PCIe GBE Family Controller
Local IP: 192.168.3.2
Local Mac: 0C-9D-92-1A-DE-A6
Linux
linux下很多信息都是存放着系统的/proc目录下,因此读文件就可以获取到了
代码:
#include <stdio.h> #include <stdlib.h> #include <string.h> // mostly need to read the linux config files to get system info // ---- get os info ---- // void getOsInfo() { FILE *fp = fopen("/proc/version", "r"); if(NULL == fp) printf("failed to open version\n"); char szTest[1000] = {0}; while(!feof(fp)) { memset(szTest, 0, sizeof(szTest)); fgets(szTest, sizeof(szTest) - 1, fp); // leave out \n printf("%s", szTest); } fclose(fp); } // ---- get cpu info ---- // void getCpuInfo() { FILE *fp = fopen("/proc/cpuinfo", "r"); if(NULL == fp) printf("failed to open cpuinfo\n"); char szTest[1000] = {0}; // read file line by line while(!feof(fp)) { memset(szTest, 0, sizeof(szTest)); fgets(szTest, sizeof(szTest) - 1, fp); // leave out \n printf("%s", szTest); } fclose(fp); } // ---- get memory info ---- // void getMemoryInfo() { FILE *fp = fopen("/proc/meminfo", "r"); if(NULL == fp) printf("failed to open meminfo\n"); char szTest[1000] = {0}; while(!feof(fp)) { memset(szTest, 0, sizeof(szTest)); fgets(szTest, sizeof(szTest) - 1, fp); printf("%s", szTest); } fclose(fp); } // ---- get harddisk info ---- // #include <fcntl.h> #include <sys/ioctl.h> #include <linux/hdreg.h> void getHardDiskInfo() { // use cmd, this is the only way static struct hd_driveid hd; int fd; if ((fd = open("/dev/sda", O_RDONLY | O_NONBLOCK)) < 0) { printf("ERROR opening /dev/sda\n"); return; } if (!ioctl(fd, HDIO_GET_IDENTITY, &hd)) { printf("model ", hd.model); printf("HardDisk Serial Number: %.20s\n", hd.serial_no); } else printf("no available harddisk info"); } // ---- get network info ---- // #include <ifaddrs.h> #include <sys/socket.h> #include <arpa/inet.h> #include <sys/ioctl.h> #include <linux/if.h> void getNetworkInfo() { // get ip, works for linux and mac os, best method struct ifaddrs *ifAddrStruct = NULL; struct ifaddrs *ifa = NULL; getifaddrs(&ifAddrStruct); for (ifa = ifAddrStruct; ifa != NULL; ifa = ifa->ifa_next) { if (!ifa->ifa_addr) continue; // check if IP4 if (ifa->ifa_addr->sa_family == AF_INET) { void *tmpAddrPtr = &((struct sockaddr_in *)ifa->ifa_addr)->sin_addr; char local_ip[INET_ADDRSTRLEN]; inet_ntop(AF_INET, tmpAddrPtr, local_ip, INET_ADDRSTRLEN); // actually only need external ip printf("%s IP: %s\n", ifa->ifa_name, local_ip); } } if (ifAddrStruct) freeifaddrs(ifAddrStruct); // get mac, need to create socket first, may not work for mac os struct ifreq ifr; int fd = socket(AF_INET, SOCK_DGRAM, 0); char local_mac[128] = { 0 }; strcpy(ifr.ifr_name, "eth0"); // only need ethernet card if (0 == ioctl(fd, SIOCGIFHWADDR, &ifr)) { char temp_str[10] = { 0 }; memcpy(temp_str, ifr.ifr_hwaddr.sa_data, 6); sprintf(local_mac, "%02x-%02x-%02x-%02x-%02x-%02x", temp_str[0]&0xff, temp_str[1]&0xff, temp_str[2]&0xff, temp_str[3]&0xff, temp_str[4]&0xff, temp_str[5]&0xff); } printf("Local Mac: %s\n", local_mac); } int main(int argc, char **argv) { printf("=== os information ===\n"); getOsInfo(); printf("=== cpu infomation ===\n"); getCpuInfo(); printf("=== memory information ===\n"); getMemoryInfo(); printf("=== harddisk information ===\n"); getHardDiskInfo(); printf("=== network information ===\n"); getNetworkInfo(); return 0; }
结果:
===os information===
Linux version 4.8.6-300.fc25.x86_64 (mockbuild@bkernel02.phx2.fedoraproject.org) (gcc version 6.2.1 20160916 (Red Hat 6.2.1-2) (GCC) ) #1 SMP Tue Nov 1 12:36:38 UTC 2016
===cpu infomation===
processor : 0
vendor_id : GenuineIntel
cpu family : 6
model : 58
model name : Intel(R) Core(TM) i5-3230M CPU @ 2.60GHz
stepping : 9
microcode : 0x1b
cpu MHz : 2599.755
cache size : 3072 KB
===memory information===
MemTotal: 3061552 kB
MemFree: 89584 kB
MemAvailable: 596876 kB
Buffers: 70372 kB
Cached: 707548 kB
SwapCached: 392 kB
=== harddisk information ===
HardDisk Serial Number: 0520B6776730A1F4
=== network information ===
lo IP: 127.0.0.1
eth0 IP: 192.168.136.140
Local Mac: 00-0c-29-ec-7a-80
---------------------
- 文章2305
- 用户1336
- 访客11455848
没有努力,天份不代表什么。
MySQL 数据库优化
This function has none of DETERMINISTIC, NO SQL, or READS SQL DATA in its de
免ROOT实现模拟点击任意位置
Mobaxterm终端神器
CreateProcessW要注意的细节问题
Autonomous NAT Traversal
【教程】win10 彻底卸载edge浏览器
eclipse工程基于Xposed的一个简单Hook
排名前5的开源在线机器学习
Mac OS最简单及(Karabiner)快捷键设置
发一款C++编写的麻将
VMware NAT端口映射外网访问虚拟机linux
独家发布最新可用My-AutoPost——wordpress 采集器