欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Linux下如何使用C++獲取硬件信息

 更新時間:2025年04月20日 15:51:07   作者:ACE叫牌  
這篇文章主要為大家詳細介紹了如何使用C++實現(xiàn)獲取CPU,主板,磁盤,BIOS信息等硬件信息,文中的示例代碼講解詳細,感興趣的小伙伴可以了解下

方法

通過讀取Linux下存放硬件信息的文件來獲取CPU、主板、磁盤、BIOS信息

獲取CPU信息:讀取"/proc/cpuinfo"文件

字段及其含義:

處理器基本信息:

  • processor:處理器的邏輯編號,從 0 開始,用于標識系統(tǒng)中的每個邏輯 CPU。
  • vendor_id:CPU制造商的標識符。例如,對于 Intel CPU,可能是GenuineIntel;對于 AMD CPU,可能是AuthenticAMD。

處理器型號與家族信息

  • cpu family:CPU 所屬的家族編號。不同家族的 CPU 可能具有不同的架構和特性。例如,Intel 的酷睿系列和至強系列可能屬于不同的家族。
  • model:CPU型號編號,結合cpu family可以更準確地確定 CPU 的具體型號。
  • model name:CPU 的完整型號名稱,提供了詳細的 CPU 型號描述,如Intel® Core™ i7-10700K CPU @ 3.80GHz。

步進與微代碼信息:

  • stepping:CPU的步進編號,它標識了 CPU 的修訂版本。不同的步進可能包含對之前版本的錯誤修復或性能改進。
  • microcode:CPU微代碼版本號,微代碼是嵌入在 CPU 中的一小段代碼,用于協(xié)助 CPU 執(zhí)行指令,可以通過更新微代碼來修復 CPU 的一些問題或提升性能。

性能相關信息:

cpu MHz:CPU當前的運行頻率,單位為 MHz。這可能是動態(tài)變化的,尤其是在支持節(jié)能技術(如 Intel 的 SpeedStep 或 AMD 的

  • Cool’n’Quiet)的 CPU 上。
  • cache size:CPU 緩存的大小,通常以 KB 或 MB 為單位。緩存可以提高 CPU 訪問數(shù)據(jù)的速度,較大的緩存通常意味著更好的性能。

多處理器與多核信息:

  • physical id:物理處理器的標識符。在多處理器系統(tǒng)中,每個物理 CPU 有一個唯一的physical id。
  • siblings:同一物理 CPU上的邏輯處理器數(shù)量,即超線程技術下每個物理核心對應的邏輯核心數(shù)。例如,如果一個物理核心支持超線程,siblings可能為 2。
  • core id:每個物理核心的唯一標識符,在同一物理 CPU 內(nèi),不同的物理核心有不同的core id。
  • cpu cores:每個物理 CPU 中的核心數(shù)量,不包括超線程產(chǎn)生的邏輯核心。

其他信息:

  • apicid:高級可編程中斷控制器(APIC)標識符,用于多處理器系統(tǒng)中的中斷處理。
  • flags:CPU支持的特性標志列表,每個標志表示 CPU 支持的一種特定功能或指令集,如mmx、sse、sse2等,這些指令集可以加速特定類型的計算任務。
  • bogomips:代表 “BogusMIPS(偽每秒百萬條指令數(shù))”。它是一種對 CPU 性能的近似估計值,并非基于實際指令執(zhí)行的精確測量。這個數(shù)值最初由 Linus Torvalds引入 Linux 內(nèi)核,作為一種快速且相對簡單的方法來評估 CPU 的處理能力。
  • clflush size:緩存行刷新(Cache Line Flush)操作所涉及的緩存行大小。

獲取磁盤信息:讀取"/proc/diskstats"文件

字段及其含義(從左至右):

  • 主設備號(Major device number):在示例中為8,它標識設備類型。例如,8通常代表SCSI 磁盤設備。不同的設備類型有不同的主設備號,可用于識別設備所屬的大類。
  • 次設備號(Minor device number):示例中的0,它用于在同一主設備類型下進一步區(qū)分具體的設備實例。主設備號和次設備號共同唯一標識系統(tǒng)中的一個塊設備。
  • 設備名稱(Device name):這里是sda,這是設備在系統(tǒng)中的名稱,通常對應/dev目錄下的設備文件名,方便用戶和系統(tǒng)管理員識別和操作具體設備。
  • 讀完成次數(shù)(Reads completed successfully):212553,表示從設備成功完成的讀操作次數(shù)。每次成功讀取數(shù)據(jù)塊,該計數(shù)增加。
  • 讀合并次數(shù)(Reads merged):14992,系統(tǒng)有時會合并相鄰的讀請求以提高 I/O 效率,該字段統(tǒng)計了合并讀操作的次數(shù)。合并讀可以減少I/O 操作的總次數(shù),提升性能。
  • 讀扇區(qū)數(shù)(Sectors read):1469963,表示從設備讀取的扇區(qū)總數(shù)。一個扇區(qū)通常是 512 字節(jié)(在現(xiàn)代設備中也可能是 4096字節(jié)等),這個數(shù)字反映了讀取的數(shù)據(jù)量(以扇區(qū)為單位)。
  • 讀操作花費的毫秒數(shù)(Time spent reading (ms)):334512,累計花費在讀操作上的時間,以毫秒為單位。它反映了設備讀取數(shù)據(jù)所花費的總時間,可用于評估讀性能。
  • 寫完成次數(shù)(Writes completed successfully):1005650,表示向設備成功完成的寫操作次數(shù)。每次成功寫入數(shù)據(jù)塊,該計數(shù)增加。
  • 寫合并次數(shù)(Writes merged):121259,類似于讀合并,系統(tǒng)會合并相鄰的寫請求,該字段統(tǒng)計了合并寫操作的次數(shù),以提高寫性能。
  • 寫扇區(qū)數(shù)(Sectors written):6743707,表示向設備寫入的扇區(qū)總數(shù),反映了寫入的數(shù)據(jù)量(以扇區(qū)為單位)。
  • 寫操作花費的毫秒數(shù)(Time spent writing (ms)):10052256,累計花費在寫操作上的時間,以毫秒為單位,可用于評估寫性能。
  • 當前I/O 操作數(shù)(I/O requests currently in progress):0,表示當前正在進行的 I/O請求數(shù)量。如果這個值持續(xù)不為零,可能表示設備出現(xiàn)了 I/O 瓶頸。
  • I/O操作花費的總毫秒數(shù)(Time spent doing I/O (ms)):343049,累計花費在所有 I/O操作(讀和寫)上的時間,以毫秒為單位。
  • 加權的I/O 操作花費的毫秒數(shù)(Weighted time spent doing I/O (ms)):10386768,這是一個加權時間,考慮了I/O 請求的排隊時間等因素,能更全面地反映 I/O 操作對系統(tǒng)資源的占用情況。

獲取BIOS信息有兩種方法

1.讀取文件

可以通過讀取三個文件分別獲得BIOS供應商名稱、BIOS版本號、BIOS發(fā)布日期,分別是:

BIOS供應商名稱:/sys/class/dmi/id/bios_vendor

BIOS版本號:/sys/class/dmi/id/bios_version

BIOS發(fā)布日期:/sys/class/dmi/id/bios_date

優(yōu)點:

無需 root 權限??:普通用戶即可訪問。無額外依賴??:直接通過文件接口讀取,避免調(diào)用外部命令。??適用于容器/虛擬化環(huán)境??:即使 DMI 信息被限制,部分字段仍可能可用。

缺點:獲取到的信息少。

2.使用dmidecode命令

工作方式:dmidecode的工作方式就是解析DMI表

命令:sudo dmidecode -t bios

字段含義:

  • Vendor:BIOS供應商名稱
  • Version:BIOS版本號
  • Release Date:BIOS發(fā)布日期
  • Address:BIOS在內(nèi)存中的物理地址(十六進制)
  • Runtime Size?:BIOS運行時占用的內(nèi)存大小
  • ROM Size:存儲 BIOS固件的 ROM(只讀存儲器)容量
  • Characteristics:BIOS支持的特性列表,每個特性對應一個硬件或軟件功能
  • ??BIOS Revision?:BIOS 的修訂版本號(可能與 Version 不同)
  • Firmware Revision?:主板固件的版本號(可能與 BIOS 版本分離)

優(yōu)點: 獲取的信息更多、更全面。

缺點:?

  • 權限要求??:dmidecode 需要 ??root 權限?? 才能讀取完整 DMI表,如果運行程序的用戶不是root用戶會失敗。
  • 依賴性??:dmidecode方法需要安裝該工具(通常默認已安裝),常見的安裝目錄。有"/usr/sbin/dmidecode"、“/sbin/dmidecode”、“/usr/local/sbin/dmidecode”。代碼在調(diào)用命令前需要先驗證是否存在路徑。
  • 適用性??:虛擬化環(huán)境(如容器)中可能無法提供完整的DMI信息。

獲取主板信息有兩種方法

1.讀取文件

可以通過讀取文件分別獲得主板供應商名稱、主板版本號、主板型號,主板序列號,主板資產(chǎn)標簽分別是:

主板供應商名稱:/sys/class/dmi/id/board_vendor

主板版本號:/sys/class/dmi/id/board_version

主板型號:/sys/class/dmi/id/board_name

主板序列號:/sys/class/dmi/id/board_serial,讀取該文件需要root權限,所以代碼中無法依靠讀取文件獲取,但是可以通過dmidecode命令獲?。ㄒ娤挛模?/p>

主板資產(chǎn)標簽:/sys/class/dmi/id/board_asset_tag

優(yōu)點:

無需 root 權限??:普通用戶即可訪問。無額外依賴??:直接通過文件接口讀取,避免調(diào)用外部命令。??適用于容器/虛擬化環(huán)境??:即使 DMI 信息被限制,部分字段仍可能可用。

缺點: 獲取到的信息少。

2.使用dmidecode命令

工作方式:dmidecode的工作方式就是解析DMI表

命令:sudo dmidecode -t baseboard

字段含義:

  • Manufacturer:主板制造商
  • Product Name: 主板型號
  • Version:主板版本號,None為未指定
  • Serial Number:主板序列號,None為未指定
  • Asset Tag: 資產(chǎn)標簽,Not Specified為未指定
  • Features:主板特殊功能,None為無特殊功能
  • Location In Chassis:主板在機箱中的位置,Not Specified未記錄
  • Chassis Handle:關聯(lián)的機箱記錄句柄,0x0000為未關聯(lián)或默認值
  • Type:主板類型,Unknown為未明確
  • Contained Object Handle:關聯(lián)的子設備,0表示無關聯(lián)

優(yōu)點: 獲取的信息更多、更全面。

缺點:?

  • 權限要求??:dmidecode 需要 ??root 權限?? 才能讀取完整 DMI表,如果運行程序的用戶不是root用戶會失敗。
  • 依賴性??:dmidecode方法需要安裝該工具(通常默認已安裝),常見的安裝目錄。有"/usr/sbin/dmidecode"、“/sbin/dmidecode”、“/usr/local/sbin/dmidecode”。代碼在調(diào)用命令前需要先驗證是否存在路徑。
  • 適用性??:虛擬化環(huán)境(如容器)中可能無法提供完整的DMI信息。

代碼部分

LinuxHardwareInfo.h

#pragma once

#include <iostream>
#include <fstream>
#include <string>
#include <vector>
#include <string.h>
#include <sstream>
#include <memory>
#include <stdexcept>
#include <array>
#include <sys/types.h>
#include <unistd.h>
#include <stdio.h>
#include <unordered_map>
#include <functional>

// CPU信息結構體
struct CPUInfo
{
    std::string processor_;              // CPU 的邏輯編號
    std::string vendor_id_;              // CPU 制造商的標識符
    std::string cpu_family_;             // CPU 所屬的家族編號
    std::string model_;                  // CPU 型號編號
    std::string model_name_;             // CPU 的完整型號名稱
    std::string stepping_;               // CPU 的步進編號
    std::string microcode_;              // CPU 微代碼版本號
    std::string cpu_freq_;               // CPU 當前的運行頻率,單位為 MHz
    std::string cache_size_;             // CPU 緩存的大小,單位為KB
    std::string physical_id_;            // CPU 的標識符
    std::string siblings_;               // 同一物理 CPU 上的邏輯處理器數(shù)量
    std::string core_id_;                // 每個物理核心的唯一標識符
    std::string cpu_cores_;              // 每個物理 CPU 中的核心數(shù)量,不包括超線程產(chǎn)生的邏輯核心
    std::string clflush_size_;           // 緩存行刷新(Cache Line Flush)操作所涉及的緩存行大小
};

// 磁盤信息結構體
struct DiskStatsInfo
{
    std::string major_device_num_;          // 主設備號,標識設備類型
    std::string minor_device_num_;          // 次設備號,用于在同一主設備類型下進一步區(qū)分具體的設備實例,主設備號和次設備號共同唯一標識系統(tǒng)中的一個塊設備
    std::string device_name_;               // 磁盤名稱,對應/dev目錄下的設備文件名
    std::string read_completed_;            // 從設備成功完成的讀操作次數(shù),每次成功讀取數(shù)據(jù)塊,該計數(shù)增加
    std::string read_merged_;               // 合并讀操作次數(shù)
    std::string read_sectors_;              // 從設備讀取的扇區(qū)總數(shù)
    std::string read_time_spent_;           // 累計花費在讀操作上的時間,單位毫秒
    std::string write_completed_;           // 向設備成功完成的寫操作次數(shù),每次成功寫入數(shù)據(jù)塊,該計數(shù)增加
    std::string write_merged_;              // 合并寫操作次數(shù)
    std::string write_sectors_;             // 向設備寫入的扇區(qū)總數(shù)
    std::string write_time_spent_;          // 累計花費在寫操作上的時間,單位毫秒
};

// BIOS信息結構體,細節(jié)信息通過dmidecode命令獲取到的
struct BIOSMoreInfo
{
    // 基礎信息
    std::string     vendor_;                    // BIOS供應商
    std::string     version_;                   // BIOS版本
    std::string     date_;                      // BIOS發(fā)布日期
    
    // 細節(jié)信息
    std::string   address_;                     // BIOS 在內(nèi)存中的物理地址(十六進制)
    std::string   runtime_size_;                // BIOS運行時占用的內(nèi)存大小,單位為bytes
    std::string   rom_size_;                    // 存儲 BIOS 固件的 ROM(只讀存儲器)容量,單位為kB
    std::string   bios_revision_;               // BIOS的修訂版本號,可能與Version不同
    std::string   firmware_revisioin_;          // 主板固件版本號
};

// 主板信息結構體,細節(jié)信息通過dmidecode命令獲取
struct BaseboardMoreInfo
{
    // 基礎信息
    std::string     vendor_;                    // 主板供應商
    std::string     version_;                   // 主板版本號
    std::string     name_;                      // 主板型號
    std::string     asset_tag_;                 // 主板資產(chǎn)標簽

    // 細節(jié)信息
    std::string     serial_num_;                // 主板序列號
    std::string     location_in_chassis_;       // 主板在機箱中的位置
    std::string     type_;                      // 主板類型
};

// 檢測當前運行環(huán)境是否可以使用dmidecode命令
#ifndef IsUseDmidecodeCommand
#define IsUseDmidecodeCommand()\
    bool is_use_dmidecode = false;\
    \
    if(geteuid() == 0 && FindDmidecodePath())\
        is_use_dmidecode = true;\
    else\
        std::cout << "當前運行環(huán)境不支持dmidecode命令, 只獲取基本信息" << std::endl;
#endif

// 根據(jù):進行字符串切割并去除兩端空格得到key和value字符串
#ifndef SplitRemoveWhite
#define SplitRemoveWhite(_line)\
    size_t pos = _line.find(':');\
    \
    if (pos == std::string::npos)\
        return;\
    \
    std::string key = _line.substr(0, pos);\
    std::string value = _line.substr(pos + 1);\
    \
    RemoveWhiteSpace(value);\
    RemoveWhiteSpace(key);
#endif

// Linux下獲取CPU的所有信息
class LinuxHardwareInfo
{
public:

    LinuxHardwareInfo();
    ~LinuxHardwareInfo();

    /*
        @brief 獲取CPU的所有信息
        @param _cpu_infos 會有多個cpu的信息
    */
    void GetProcessorAllInfo(std::vector<CPUInfo>& _cpu_infos);

    /*
        @brief 獲取磁盤的所有信息
        @param _disk_infos 會有多個磁盤信息
    */
    void GetDiskStatsAllInfo(std::vector<DiskStatsInfo>& _disk_infos);

    /*
        @brief 獲取BIOS的信息
            1、該接口會先使用demidecode命令獲取BIOS更詳細的信息,如果檢測到系統(tǒng)的demidecode命令無法使用,改用讀取文件的方式只獲取BISO
                基本信息?。。?
            2、該接口返回true的情況為:Linux系統(tǒng)已經(jīng)安裝demidecode命令,并且運行程序的用戶為root用戶
        @param _bios_info BIOS信息結構體
        @return true表示demidecode命令可以使用,獲取到了更詳細的信息;false說明當前運行環(huán)境的demidecode命令無法使用,只能獲取基本信息。
    */
    bool GetBIOSAllInfo(BIOSMoreInfo& _bios_info);

    /*
        @brief 獲取主板的信息
            1、該接口會先使用demidecode命令獲取BIOS更詳細的信息,如果檢測到系統(tǒng)的demidecode命令無法使用,改用讀取文件的方式只獲取主板
                基本信息?。?!
            2、該接口返回true的情況為:Linux系統(tǒng)已經(jīng)安裝demidecode命令,并且運行程序的用戶為root用戶
        @param _board_info 主板信息結構體
        @return true表示demidecode命令可以使用,獲取到了更詳細的信息;false說明當前運行環(huán)境的demidecode命令無法使用,只能獲取基本信息。
    */
    bool GetBoardAllInfo(BaseboardMoreInfo& _board_info);

private:

    /*
        @brief 通過讀取文件的方式獲取BIOS基本信息
        @param BIOS基本信息
    */
    void GetBIOSBasicInfo(BIOSMoreInfo& _bios_info);

    /*
        @brief 通過讀取文件的方式獲取主板基本信息
        @param 主板基本信息
    */
    void GetBoardBasicInfo(BaseboardMoreInfo& _board_info);

    /*
        @brief 去除字符串兩端的空白字符,包括空格、\t等
        @param _str 源字符串
    */
    void RemoveWhiteSpace(std::string& _str);

    /*
        @brief 解析CPU文件信息的一行
        @param _line 一行字符串
        @param _cpu_info 存儲數(shù)據(jù)的結構體
    */
    void ParseProcessorLine(const std::string& _line, CPUInfo& _cpu_info);

    /*
        @brief 處理BISO信息的一行
        @param _line 一行字符串
        @param _bios_info BISO數(shù)據(jù)結構體
    */
    void ProcessBIOSLine(const std::string& _line, BIOSMoreInfo& _bios_info);

    /*
        @brief 處理主板信息的一行
        @param _line 一行字符串
        @param _board_info 主板數(shù)據(jù)結構體
    */
    void ProcessBoardLine(const std::string& _line, BaseboardMoreInfo& _board_info);

    /*
        @brief 檢查 dmidecode 是否存在并返回其完整路徑
        @return true表示存在,false表示不存在
    */
    bool FindDmidecodePath();

    /*
        @brief 執(zhí)行命令并捕獲輸出
        @param cmd 命令
        @return 輸出的字符串
    */
    std::string GetStrByCommand(const char* _cmd);

    /*
        @brief 按照換行符進行切割
        @param _str 源字符串
        @return 切割后的集合
    */
    std::vector<std::string> SplitByNewline(const std::string& _str);

    /*
        @brief 更新主板結構體處理器
        @param _key 結構體成員對應的key值
        @param value 結構體成員值
    */
    void UpdateBoardInfo(BaseboardMoreInfo& _board_info, const std::string& _key, const std::string& _value);

    /*
        @brief 更新BIOS結構體處理器
        @param _key 結構體成員對應的key值
        @param value 結構體成員值
    */
    void UpdateBIOSInfo(BIOSMoreInfo& _bios_info, const std::string& _key, const std::string& _value);

    /*
        @brief 更新CPU結構體處理器
        @param _key 結構體成員對應的key值
        @param value 結構體成員值
    */
    void UpdateCpuInfo(CPUInfo& _cpu_info, const std::string& _key, const std::string& _value);

private:

    // 成員指針類型別名
    using BoardMemberPtr = std::string BaseboardMoreInfo::*;

    using BIOSMemberPtr = std::string BIOSMoreInfo::*;

    using CpuMemberPtr = std::string CPUInfo::*;

    const std::string cpu_file_;        // Linux系統(tǒng)下cpu信息的存儲路徑

    const std::string disk_file_;       // Linux系統(tǒng)下磁盤信息的存儲路徑

    const std::string bios_dir_;                             // Linux系統(tǒng)下存放BIOS信息的目錄
    const std::vector<std::string>  bios_files_name_;        // Linux系統(tǒng)下存放BIOS信息的所有文件名

    const std::string board_dir_;                             // Linux系統(tǒng)下存放主板信息的目錄
    const std::vector<std::string>  board_files_name_;        // Linux系統(tǒng)下存放主板信息的所有文件名

    const std::vector<std::string>  dmidecode_command_path_; // Linux系統(tǒng)下常見的demidecode命令的完整路徑,檢測系統(tǒng)是否安裝該命令會用到

    std::unordered_map<std::string, std::function<void(std::string)>>   process_board_value_map_;           // 給主板信息結構體賦值    
};

LinuxHardwareInfo.cpp

#include "LinuxHardwareInfo.h"

LinuxHardwareInfo::LinuxHardwareInfo()
    : cpu_file_("/proc/cpuinfo")
    , disk_file_("/proc/diskstats")
    , bios_dir_("/sys/class/dmi/id/")
    , bios_files_name_({"bios_vendor","bios_version","bios_date"})
    , dmidecode_command_path_({"/usr/sbin/dmidecode", "/sbin/dmidecode", "/usr/local/sbin/dmidecode"})
    , board_dir_("/sys/class/dmi/id/")
    , board_files_name_({"board_vendor","board_version","board_name","board_asset_tag"})
{
}

LinuxHardwareInfo::~LinuxHardwareInfo()
{
}

void LinuxHardwareInfo::GetProcessorAllInfo(std::vector<CPUInfo> &_cpu_info)
{
    std::ifstream file(cpu_file_);
    
    if (!file.is_open())
    {
        std::cerr << "CPU文件: " << cpu_file_ << "打開失敗" << std::endl;

        return;
    }

    CPUInfo cpuInfo;
    std::string line;
    while (std::getline(file, line))
    {
        if (line.empty())
        {
            // 讀取下一個cpu的信息
            if(!cpuInfo.model_name_.empty()) 
            {
                _cpu_info.push_back(cpuInfo);
                cpuInfo = CPUInfo();
            }
        }
        else
            ParseProcessorLine(line, cpuInfo);
    }

    // 添加最后一個CPU信息
    if (!cpuInfo.model_name_.empty()) 
    {
        _cpu_info.push_back(cpuInfo);
    }

    file.close();
}

void LinuxHardwareInfo::GetDiskStatsAllInfo(std::vector<DiskStatsInfo> &_disk_infos)
{
    std::ifstream disk_stats_file(disk_file_);
    if (!disk_stats_file.is_open()) 
    {
        std::cerr << "磁盤文件: " << disk_file_ << "打開失敗" << std::endl;
     
        return;
    }

    std::string line;
    while (std::getline(disk_stats_file, line))
    {
        std::istringstream iss(line);

        DiskStatsInfo diskStats;

        std::string inFlight, ioTicks, timeInQueue;

        if (!(iss >> diskStats.major_device_num_ >> diskStats.minor_device_num_ >> diskStats.device_name_
                  >> diskStats.read_completed_ >> diskStats.read_merged_ >> diskStats.read_sectors_
                  >> diskStats.read_time_spent_ >> diskStats.write_completed_ 
                  >> diskStats.write_merged_ >> diskStats.write_sectors_ >> diskStats.write_time_spent_ 
                  >> inFlight >> ioTicks >> timeInQueue)) 
        {
            continue;
        }

        _disk_infos.push_back(diskStats);
    }

    disk_stats_file.close();

    return;
}

bool LinuxHardwareInfo::GetBIOSAllInfo(BIOSMoreInfo &_bios_info)
{
    IsUseDmidecodeCommand()

    if(is_use_dmidecode)   // 使用dmidecode命令獲取更詳細的BISO信息
    {
        try
        {
            // 對獲取到的命令輸出進行字符串切割
            std::vector<std::string> bios_info_vec = SplitByNewline(GetStrByCommand("dmidecode -t bios"));

            for(const auto& line : bios_info_vec)
            {
                ProcessBIOSLine(line, _bios_info);
            }

        } catch (const std::exception& e)
        {
            std::cerr << "dmidecode命令執(zhí)行錯誤: " << e.what() << std::endl;

            // 拋出異常后只獲取基本信息
            GetBIOSBasicInfo(_bios_info);

            return false;
        }
    }
    else    // 只獲取基本信息
        GetBIOSBasicInfo(_bios_info);

    return is_use_dmidecode;
}

bool LinuxHardwareInfo::GetBoardAllInfo(BaseboardMoreInfo &_board_info)
{
    IsUseDmidecodeCommand()

    if(is_use_dmidecode)   // 使用dmidecode命令獲取更詳細的主板信息
    {
        try
        {
            // 對獲取到的命令輸出進行字符串切割
            std::vector<std::string> board_info_vec = SplitByNewline(GetStrByCommand("dmidecode -t baseboard"));

            bool is_parse = false;
            for(const auto& line : board_info_vec)
            {
                if(line == "Base Board Information")
                    is_parse = true;
                else if(line.empty())
                    is_parse = false;
                
                if(is_parse)
                    ProcessBoardLine(line, _board_info);
            }

        } catch (const std::exception& e)
        {
            std::cerr << "dmidecode命令執(zhí)行錯誤: " << e.what() << std::endl;

            // 拋出異常后只獲取基本信息
            GetBoardBasicInfo(_board_info);

            return false;
        }
    }
    else    // 只獲取基本信息
        GetBoardBasicInfo(_board_info);

    return is_use_dmidecode;
}

void LinuxHardwareInfo::GetBIOSBasicInfo(BIOSMoreInfo &_bios_info)
{
    for(const auto& file_name : bios_files_name_)
    {
        // bios文件路徑
        std::string path = bios_dir_ + file_name;
        std::ifstream file(path);
        if (!file.is_open())
        {
            std::cerr << "BIOS文件: " << path << "打開失敗" << std::endl;
            return;
        }

        std::string value;
        std::getline(file, value);
        
        UpdateBIOSInfo(_bios_info,file_name,value);
    }
}

void LinuxHardwareInfo::GetBoardBasicInfo(BaseboardMoreInfo &_board_info)
{
    for(const auto& file_name : board_files_name_)
    {
        // board文件路徑
        std::string path = board_dir_ + file_name;
        std::ifstream file(path);
        if (!file.is_open())
        {
            std::cerr << "主板文件: " << path << "打開失敗" << std::endl;
            return;
        }

        std::string value;
        std::getline(file, value);
        
        UpdateBoardInfo(_board_info,file_name,value);
    }
}

void LinuxHardwareInfo::RemoveWhiteSpace(std::string &_str)
{
    int head_idx = 0, tail_idx = _str.length() - 1;

    bool head_flag = false, tail_flag = false;

    while (head_idx != tail_idx)
    {
        // 使用std::isspace方法判斷空白字符,因為會有\(zhòng)t等情況
        if(!head_flag && std::isspace(_str[head_idx]))
            head_idx++;
        else
            head_flag = true;

        if(!tail_flag && std::isspace(_str[tail_idx]))
            tail_idx--;
        else
            tail_flag = true;

        if(head_flag && tail_flag)
            break;
    }

    _str = _str.substr(head_idx, tail_idx - head_idx + 1);

    return;
}

void LinuxHardwareInfo::ParseProcessorLine(const std::string &_line, CPUInfo &_cpu_info)
{
    SplitRemoveWhite(_line)

    UpdateCpuInfo(_cpu_info,key,value);
}

void LinuxHardwareInfo::ProcessBIOSLine(const std::string &_line, BIOSMoreInfo &_bios_info)
{
    SplitRemoveWhite(_line)

    UpdateBIOSInfo(_bios_info,key,value);
}

void LinuxHardwareInfo::ProcessBoardLine(const std::string &_line, BaseboardMoreInfo &_board_info)
{
    SplitRemoveWhite(_line)

    UpdateBoardInfo(_board_info,key,value);
}

bool LinuxHardwareInfo::FindDmidecodePath()
{
    for (const auto& path : dmidecode_command_path_) 
    {
        if (access(path.c_str(), X_OK) == 0) 
        {
            return true; // 找到有效路徑
        }
    }

    return false;
}

std::string LinuxHardwareInfo::GetStrByCommand(const char *_cmd)
{
    std::array<char, 128> buffer;
    std::string result;
    std::unique_ptr<FILE, decltype(&pclose)> pipe(popen(_cmd, "r"), pclose);

    if (!pipe) 
    {
        throw std::runtime_error("Failed to execute command");
    }

    while (fgets(buffer.data(), buffer.size(), pipe.get()) != nullptr) 
    {
        result += buffer.data();
    }

    return result;
}

std::vector<std::string> LinuxHardwareInfo::SplitByNewline(const std::string &_str)
{
    std::vector<std::string> lines;
    std::istringstream iss(_str);
    std::string line;   
    
    while (std::getline(iss, line, '\n')) 
    {
        lines.push_back(line);
    }

    return lines;
}

void LinuxHardwareInfo::UpdateBoardInfo(BaseboardMoreInfo &_board_info, const std::string &_key, const std::string &_value)
{
    static const std::unordered_map<std::string, BoardMemberPtr> keys_map = {
        {"Manufacturer",   &BaseboardMoreInfo::vendor_},
        {"Product Name",   &BaseboardMoreInfo::name_},
        {"Version",  &BaseboardMoreInfo::version_},
        {"Serial Number",       &BaseboardMoreInfo::serial_num_},
        {"Asset Tag",  &BaseboardMoreInfo::asset_tag_},
        {"Location In Chassis",    &BaseboardMoreInfo::location_in_chassis_},
        {"Type",    &BaseboardMoreInfo::type_},
        {"board_vendor",   &BaseboardMoreInfo::vendor_},
        {"board_name",   &BaseboardMoreInfo::name_},
        {"board_version",   &BaseboardMoreInfo::version_},
        {"board_asset_tag",   &BaseboardMoreInfo::asset_tag_},
        {"board_serial",   &BaseboardMoreInfo::serial_num_}
    };

    if (auto it = keys_map.find(_key); it != keys_map.end()) 
    {
        _board_info.*(it->second) = _value;
    }
    // else
    //     std::cerr << "解析出" << _key << "和" << _value << std::endl;
}

void LinuxHardwareInfo::UpdateBIOSInfo(BIOSMoreInfo &_bios_info, const std::string &_key, const std::string &_value)
{
    static const std::unordered_map<std::string, BIOSMemberPtr> keys_map = {
        {"Vendor",   &BIOSMoreInfo::vendor_},
        {"Release Date",   &BIOSMoreInfo::date_},
        {"Version",  &BIOSMoreInfo::version_},
        {"Address",       &BIOSMoreInfo::address_},
        {"Runtime Size",  &BIOSMoreInfo::runtime_size_},
        {"ROM Size",    &BIOSMoreInfo::rom_size_},
        {"BIOS Revision",    &BIOSMoreInfo::bios_revision_},
        {"Firmware Revision",    &BIOSMoreInfo::firmware_revisioin_},
        {"bios_vendor",   &BIOSMoreInfo::vendor_},
        {"bios_date",   &BIOSMoreInfo::date_},
        {"bios_version",   &BIOSMoreInfo::version_}
    };

    if (auto it = keys_map.find(_key); it != keys_map.end()) 
    {
        // 部分字段帶有單位,去除單位
        if(_value.find(" ") != std::string::npos)
        {
            size_t pos = _value.find(" ");

            _bios_info.*(it->second) = _value.substr(0, pos);
        }
        else
            _bios_info.*(it->second) = _value;
    }
    // else
    //     std::cerr << "解析出" << _key << "和" << _value << std::endl;
}

void LinuxHardwareInfo::UpdateCpuInfo(CPUInfo& _cpu_info, const std::string &_key, const std::string &_value)
{
    static const std::unordered_map<std::string, CpuMemberPtr> keys_map = {
        {"processor",   &CPUInfo::processor_},
        {"vendor_id",   &CPUInfo::vendor_id_},
        {"cpu family",  &CPUInfo::cpu_family_},
        {"model",       &CPUInfo::model_},
        {"model name",  &CPUInfo::model_name_},
        {"stepping",    &CPUInfo::stepping_},
        {"microcode",    &CPUInfo::microcode_},
        {"cpu MHz",    &CPUInfo::cpu_freq_},
        {"physical id",   &CPUInfo::physical_id_},
        {"siblings",   &CPUInfo::siblings_},
        {"core id",   &CPUInfo::core_id_},
        {"cpu cores",   &CPUInfo::cpu_cores_},
        {"clflush size",   &CPUInfo::clflush_size_}
    };

    if (auto it = keys_map.find(_key); it != keys_map.end()) 
    {
        // 部分字段帶有單位,去除單位
        if(_value.find(" ") != std::string::npos)
        {
            size_t pos = _value.find(" ");

            _cpu_info.*(it->second) = _value.substr(0, pos);
        }
        else
            _cpu_info.*(it->second) = _value;
    }
    // else
    //     std::cerr << "解析出" << _key << "和" << _value << std::endl;
}

main.cpp

#include <iostream>
#include "LinuxHardwareInfo.h"
int main()
{
    LinuxHardwareInfo info;

    std::cout << "*************************CPU信息*************************" << std::endl;

    std::vector<CPUInfo> cpuInfos;
    info.GetProcessorAllInfo(cpuInfos);

    for (const auto& cpuInfo : cpuInfos)
    {
        std::cout << "-------------------------" << std::endl;
        std::cout << "processor: " << cpuInfo.processor_ << std::endl;
        std::cout << "Vendor ID: " << cpuInfo.vendor_id_ << std::endl;
        std::cout << "CPU Family: " << cpuInfo.cpu_family_ << std::endl;
        std::cout << "Model: " << cpuInfo.model_ << std::endl;
        std::cout << "Model Name: " << cpuInfo.model_name_ << std::endl;
        std::cout << "Stepping: " << cpuInfo.stepping_ << std::endl;
        std::cout << "Microcode: " << cpuInfo.microcode_ << std::endl;
        std::cout << "CPU MHz: " << cpuInfo.cpu_freq_ << std::endl;
        std::cout << "Cache Size: " << cpuInfo.cache_size_ << std::endl;
        std::cout << "Physical ID: " << cpuInfo.physical_id_ << std::endl;
        std::cout << "Siblings: " << cpuInfo.siblings_ << std::endl;
        std::cout << "Core ID: " << cpuInfo.core_id_ << std::endl;
        std::cout << "CPU Cores: " << cpuInfo.cpu_cores_ << std::endl;
        std::cout << "clflush size: " << cpuInfo.clflush_size_ << std::endl;
        std::cout << "-------------------------" << std::endl;
    }

    std::cout << "*************************CPU信息*************************" << std::endl;

    std::cout << "*************************磁盤信息*************************" << std::endl;

    std::vector<DiskStatsInfo> disk_infos;
    info.GetDiskStatsAllInfo(disk_infos);

    for (const auto& diskStats : disk_infos) 
    {
        std::cout << "-------------------------" << std::endl;
        std::cout << "主設備號: " << diskStats.major_device_num_ << std::endl;
        std::cout << "次設備號: " << diskStats.minor_device_num_ << std::endl;
        std::cout << "磁盤名稱: " << diskStats.device_name_ << std::endl;
        std::cout << "完成的讀操作次數(shù): " << diskStats.read_completed_ << std::endl;
        std::cout << "合并讀操作次數(shù): " << diskStats.read_merged_ << std::endl;
        std::cout << "讀取的扇區(qū)總數(shù): " << diskStats.read_sectors_ << std::endl;
        std::cout << "花費在讀操作上的時間: " << diskStats.read_time_spent_ << std::endl;
        std::cout << "完成的寫操作次數(shù): " << diskStats.write_completed_ << std::endl;
        std::cout << "合并寫操作次數(shù): " << diskStats.write_merged_ << std::endl;
        std::cout << "寫入的扇區(qū)總數(shù): " << diskStats.write_sectors_ << std::endl;
        std::cout << "花費在寫操作上的時間: " << diskStats.write_time_spent_ << std::endl;
        std::cout << "-------------------------" << std::endl;
    }
    std::cout << "*************************磁盤信息*************************" << std::endl;

    std::cout << "*************************BIOS信息*************************" << std::endl;

    BIOSMoreInfo bios_info;
    info.GetBIOSAllInfo(bios_info);

    std::cout << "BIOS版本號: " << bios_info.version_ << std::endl;
    std::cout << "BIOS供應商: " << bios_info.vendor_ << std::endl;
    std::cout << "BIOS發(fā)布日期: " << bios_info.date_ << std::endl;
    std::cout << "BIOS 在內(nèi)存中的物理地址: " << bios_info.address_ << std::endl;
    std::cout << "BIOS運行時占用的內(nèi)存大小: " << bios_info.runtime_size_ << std::endl;
    std::cout << "存儲BIOS固件的ROM(只讀存儲器)容量: " << bios_info.rom_size_ << std::endl;
    std::cout << "BIOS 的修訂版本號: " << bios_info.bios_revision_ << std::endl;
    std::cout << "主板固件的版本號: " << bios_info.firmware_revisioin_ << std::endl;
    std::cout << "*************************BIOS信息*************************" << std::endl;
 
    std::cout << "*************************主板信息*************************" << std::endl;
 
    BaseboardMoreInfo board_info;
    info.GetBoardAllInfo(board_info);
 
    std::cout << "主板版本號: " << board_info.version_ << std::endl;
    std::cout << "主板供應商: " << board_info.vendor_ << std::endl;
    std::cout << "主板型號: " << board_info.name_ << std::endl;
    std::cout << "主板序列號: " << board_info.serial_num_ << std::endl;
    std::cout << "主板資產(chǎn)標簽: " << board_info.asset_tag_ << std::endl;
    std::cout << "主板在機箱中的位置: " << board_info.location_in_chassis_ << std::endl;
    std::cout << "主板類型: " << board_info.type_ << std::endl;
    std::cout << "*************************主板信息*************************" << std::endl;

    return 0;
}

代碼鏈接

代碼地址

部分運行結果

以上就是Linux下如何使用C++獲取硬件信息的詳細內(nèi)容,更多關于C++獲取硬件信息的資料請關注腳本之家其它相關文章!

相關文章

  • C語言中typedef的用法以及#define區(qū)別詳解

    C語言中typedef的用法以及#define區(qū)別詳解

    這篇文章主要給大家介紹了關于C語言中typedef用法以及#define區(qū)別的相關資料,typedef 是用來定義一種類型的新別名的,它不同于宏(#define),不是簡單的字符串替換。而#define只是簡單的字符串替換(原地擴展),需要的朋友可以參考下
    2021-07-07
  • C++ LeetCode1812判斷國際象棋棋盤格子顏色

    C++ LeetCode1812判斷國際象棋棋盤格子顏色

    這篇文章主要為大家介紹了C++ LeetCode1812判斷國際象棋棋盤格子顏色, 有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-12-12
  • 用C語言winform編寫滲透測試工具實現(xiàn)SQL注入功能

    用C語言winform編寫滲透測試工具實現(xiàn)SQL注入功能

    本篇文章主要介紹使用C#winform編寫滲透測試工具,實現(xiàn)SQL注入的功能。使用python編寫SQL注入腳本,基于get顯錯注入的方式進行數(shù)據(jù)庫的識別、獲取表名、獲取字段名,最終獲取用戶名和密碼;使用C#winform編寫windows客戶端軟件調(diào)用.py腳本,實現(xiàn)用戶名和密碼的獲取
    2021-08-08
  • C++?多維數(shù)組詳解

    C++?多維數(shù)組詳解

    這篇文章主要介紹了C++?獲取數(shù)組大小、多維數(shù)組操作詳解,其實C++中沒有什么多維數(shù)組,所說的多維數(shù)組其實就是數(shù)組的數(shù)組,本文給大家介紹的非常詳細,需要的朋友可以參考下
    2024-04-04
  • C語言 數(shù)據(jù)結構雙向鏈表簡單實例

    C語言 數(shù)據(jù)結構雙向鏈表簡單實例

    這篇文章主要介紹了C語言 數(shù)據(jù)結構雙向鏈表簡單實例的相關資料,需要的朋友可以參考下
    2017-03-03
  • OpenCV圖像算法實現(xiàn)圖像切分圖像合并示例

    OpenCV圖像算法實現(xiàn)圖像切分圖像合并示例

    這篇文章主要為大家介紹了python圖像算法OpenCV實現(xiàn)圖像切分圖像合并操作示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進步,早日升職加薪
    2022-06-06
  • 軟件構建工具makefile基礎講解

    軟件構建工具makefile基礎講解

    這篇文章介紹了軟件構建工具makefile,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2021-12-12
  • C++小知識:大于0并不意味著等于1

    C++小知識:大于0并不意味著等于1

    今天小編就為大家分享一篇關于C++小知識:大于0并不意味著等于1,小編覺得內(nèi)容挺不錯的,現(xiàn)在分享給大家,具有很好的參考價值,需要的朋友一起跟隨小編來看看吧
    2019-01-01
  • c++中的system(

    c++中的system("pause")的作用和含義解析

    這篇文章主要介紹了c++中system("pause")的作用和含義,非常不錯,具有參考借鑒價值,需要的朋友參考下吧
    2018-03-03
  • 仿現(xiàn)代C++智能指針實現(xiàn)引用計數(shù)

    仿現(xiàn)代C++智能指針實現(xiàn)引用計數(shù)

    這篇文章主要為大家詳細介紹了如何仿現(xiàn)代C++智能指針實現(xiàn)引用計數(shù),文中的示例代碼講解詳細,具有一定的借鑒價值,有需要的小伙伴可以了解下
    2024-03-03

最新評論