首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> 更多程式語言 >> 程式設計疑難解答

C++ 獲取處理器、硬盤、內存等硬件信息的多種方法 (Windows/Linux)

     編輯:程式設計疑難解答

概覽

C++ 無統一跨平台標準庫獲取硬件信息,需調用平台原生 API 或解析系統文件。本文匯總 Windows (註冊表、WMI、CPUID) 與 Linux (/proc、sysfs、lscpu) 的主流方案,附關鍵代碼片段。

Windows 平台方案

1. 註冊表讀取 (最簡單,適合獲取 CPU 名稱)

路徑:HKEY_LOCAL_MACHINE\HARDWARE\DESCRIPTION\System\CentralProcessor\0\ProcessorNameString

#include <windows.h>
#include <iostream>
#include <string>

std::string getCpuNameFromRegistry() {
    HKEY hKey;
    char value[256];
    DWORD bufSize = sizeof(value);
    LONG ret = RegOpenKeyExA(HKEY_LOCAL_MACHINE,
        "HARDWARE\\DESCRIPTION\\System\\CentralProcessor\\0", 0, KEY_READ, &hKey);
    if (ret == ERROR_SUCCESS) {
        RegQueryValueExA(hKey, "ProcessorNameString", nullptr, nullptr, (LPBYTE)value, &bufSize);
        RegCloseKey(hKey);
        return std::string(value);
    }
    return "Unknown";
}

2. WMI (Windows Management Instrumentation) - 功能最全

可查詢 CPU、磁盤、內存、主板、BIOS 等所有信息。需鏈接 wbemuuid.lib,代碼較繁瑣,建議封裝工具類。核心步驟:CoInitialize → CoCreateInstance(CLSID_WbemLocator) → ConnectServer → ExecQuery("SELECT * FROM Win32_Processor") → 遍歷 IEnumWbemClassObject。

3. 內嵌匯編 CPUID 指令 (底層、無依賴)

#include <array>
#include <string>

std::string getCpuBrandString() {
    std::array cpui;
    char brand[48] = {0};
    // 调用 CPUID leaf 0x80000002~0x80000004
    for (unsigned int i = 0x80000002; i <= 0x80000004; ++i) {
        __cpuid(cpui.data(), i);
        *reinterpret_cast(brand + (i - 0x80000002) * 16) = cpui[0];
        *reinterpret_cast(brand + (i - 0x80000002) * 16 + 4) = cpui[1];
        *reinterpret_cast(brand + (i - 0x80000002) * 16 + 8) = cpui[2];
        *reinterpret_cast(brand + (i - 0x80000002) * 16 + 12) = cpui[3];
    }
    return std::string(brand);
}

4. GetLogicalProcessorInformation / GetSystemInfo (核心數、架構、頁大小等)

Linux 平台方案

1. 解析 /proc/cpuinfo (CPU 詳細信息)

#include <fstream>
#include <sstream>
#include <unordered_map>

std::unordered_map parseCpuinfo() {
    std::ifstream file("/proc/cpuinfo");
    std::unordered_map info;
    std::string line;
    while (std::getline(file, line)) {
        size_t pos = line.find(':');
        if (pos != std::string::npos) {
            std::string key = line.substr(0, pos);
            std::string val = line.substr(pos + 1);
            // 只保留第一個 processor 的信息
            if (info.find(key) == info.end()) info[key] = val;
        }
    }
    return info;
}
// 使用: auto info = parseCpuinfo(); std::cout << info["model name"];

2. 解析 /proc/meminfo (內存大小)

long long getTotalMemKb() {
    std::ifstream file("/proc/meminfo");
    std::string line;
    while (std::getline(file, line)) {
        if (line.rfind("MemTotal:", 0) == 0) {
            std::istringstream iss(line);
            std::string label; long long kb;
            iss >> label >> kb;
            return kb; // 單位 KB
        }
    }
    return -1;
}

3. 使用 statvfs 獲取磁盤空間

#include <sys/statvfs.h>

struct DiskSpace { unsigned long long total, free, available; };

DiskSpace getDiskSpace(const char* path = "/") {
    struct statvfs st;
    if (statvfs(path, &st) == 0) {
        return { st.f_blocks * st.f_frsize,
                 st.f_bfree * st.f_frsize,
                 st.f_bavail * st.f_frsize };
    }
    return {0,0,0};
}

4. 命令行工具封裝 (lscpu, lsblk, free -h)

調用 popen("lscpu -J", "r") 解析 JSON 輸出 (需系統安裝 util-linux),適合快速開發、不想手寫解析器的場景。

跨平台建議

  • 項目若需長期維護,推薦使用成熟庫:**Boost.Compute** (硬件偵測)、**Qt (QSysInfo, QStorageInfo)**、**wxWidgets** 或 **POCO**。
  • 輕量級項目可自行封裝 SystemInfo 接口,編譯期根據 `_WIN32` / `__linux__` 切換實現。
  • 避免直接調用 systeminfo 或 wmic 解析文本輸出:版本差異大、本地化語言導致解析失敗、性能差。

總結表

信息類型Windows 首選Linux 首選
CPU 型號/名稱註冊表 / WMI / CPUID/proc/cpuinfo / lscpu
邏輯核心數GetLogicalProcessorInformationnproc / /proc/cpuinfo 統計 processor
物理內存大小GlobalMemoryStatusEx / WMI/proc/meminfo (MemTotal)
磁盤總/可用空間GetDiskFreeSpaceEx / WMIstatvfs / df / lsblk
主板/BIOS 信息WMI (Win32_BaseBoard)dmidecode (需 root) / /sys/class/dmi/id/

根據項目約束 (是否能引入第三方庫、是否需跨平台、權限要求) 選擇合適方案。註冊表/系統文件解析無需特殊權限,WMI/dmidecode 可能需管理員/root 權限。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved