C++获取计算机硬件信息(Windows) https://blog.csdn.net/hhy321/article/details/121258036 C++获取计算机硬件信息(Linux) https://blog.csdn.net/hhy321/article/details/127930470

“春赏百花秋望月,夏有凉风冬观雪。若无闲事挂心头,便是人间好时节。”

文章目录

1、简介1.1 Linux系统内核组成1.2 Linux系统目录结构

2、Linux命令2.1 cpuinfo2.2 upower2.3 acpi2.4 ps2.5 kill2.6 /proc/version2.7 ip2.8 filezilla2.9 vim2.10 meminfo(内存)2.11 lsblk(磁盘)2.12 lspci(网卡)2.13 lspci(主板)2.14 usb2.15 lsscsi2.16 bios2.17 dmidecode2.18 lshw2.19 hwinfo

3、Linux开发C/C++3.1 gcc3.2 g++3.3 例子1:fopen3.4 例子2:pipe3.5 例子3:system3.6 例子4:std::ifstream3.7 例子5:popen

结语

1、简介

Linux 内核并不是操作系统,它是一个完整系统的组成部分。Linux 内核控制着Linux 操作系统的基本硬件,具有很多功能,如文件管理、内存、多线程、网络 等等。

1.1 Linux系统内核组成

内核、shell、文件系统和应用程序。内核、shell和文件系统一起形成了基本的操作系统结构,它们使得用户可以运行程序、管理文件并使用系统。

Linux内核的模块分为以下几个部分:存储管理、CPU和进程管理、文件系统、设备管理和驱动、网络通信、系统的初始化和系统调用等。

应用程序是最外层,shell与应用系统进行交互,再向内是内核,也就是kernel,kernel与硬件进行交互。

有许多命令可以用来查看 Linux 系统上的硬件信息。有些命令只能够打印出像 CPU 和内存这一特定的硬件组件信息,另外一些命令可以查看多种硬件组件的信息。

1.2 Linux系统目录结构

ls /

/bin: bin 是 Binaries (二进制文件) 的缩写, 这个目录存放着最经常使用的命令。 /boot: 这里存放的是启动 Linux 时使用的一些核心文件,包括一些连接文件以及镜像文件。 /dev : dev 是 Device(设备) 的缩写, 该目录下存放的是 Linux 的外部设备,在 Linux 中访问设备的方式和访问文件的方式是相同的。 /etc: etc 是 Etcetera(等等) 的缩写,这个目录用来存放所有的系统管理所需要的配置文件和子目录。 /home: 用户的主目录,在 Linux 中,每个用户都有一个自己的目录,一般该目录名是以用户的账号命名的,如上图中的 alice、bob 和 eve。 /lib: lib 是 Library(库) 的缩写这个目录里存放着系统最基本的动态连接共享库,其作用类似于 Windows 里的 DLL 文件。几乎所有的应用程序都需要用到这些共享库。 /lost+found: 这个目录一般情况下是空的,当系统非法关机后,这里就存放了一些文件。 /media: linux 系统会自动识别一些设备,例如U盘、光驱等等,当识别后,Linux 会把识别的设备挂载到这个目录下。 /mnt: 系统提供该目录是为了让用户临时挂载别的文件系统的,我们可以将光驱挂载在 /mnt/ 上,然后进入该目录就可以查看光驱里的内容了。 /opt: opt 是 optional(可选) 的缩写,这是给主机额外安装软件所摆放的目录。比如你安装一个ORACLE数据库则就可以放到这个目录下。默认是空的。 /proc: proc 是 Processes(进程) 的缩写,/proc 是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,这个目录是一个虚拟的目录,它是系统内存的映射,我们可以通过直接访问这个目录来获取系统信息。 /root: 该目录为系统管理员,也称作超级权限者的用户主目录。 /sbin: s 就是 Super User 的意思,是 Superuser Binaries (超级用户的二进制文件) 的缩写,这里存放的是系统管理员使用的系统管理程序。 /selinux: 这个目录是 Redhat/CentOS 所特有的目录,Selinux 是一个安全机制,类似于 windows 的防火墙,但是这套机制比较复杂,这个目录就是存放selinux相关的文件的。 /srv: 该目录存放一些服务启动之后需要提取的数据。 /sys: 这是 Linux2.6 内核的一个很大的变化。该目录下安装了 2.6 内核中新出现的一个文件系统 sysfs 。 sysfs 文件系统集成了下面3种文件系统的信息:针对进程信息的 proc 文件系统、针对设备的 devfs 文件系统以及针对伪终端的 devpts 文件系统。该文件系统是内核设备树的一个直观反映。当一个内核对象被创建的时候,对应的文件和目录也在内核对象子系统中被创建。 /tmp: tmp 是 temporary(临时) 的缩写这个目录是用来存放一些临时文件的。 /usr: usr 是 unix shared resources(共享资源) 的缩写,这是一个非常重要的目录,用户的很多应用程序和文件都放在这个目录下,类似于 windows 下的 program files 目录。 /usr/bin: 系统用户使用的应用程序。 /usr/sbin: 超级用户使用的比较高级的管理程序和系统守护程序。 /usr/src: 内核源代码默认的放置目录。 /var: var 是 variable(变量) 的缩写,这个目录中存放着在不断扩充着的东西,我们习惯将那些经常被修改的目录放在这个目录下。包括各种日志文件。 /run: 是一个临时文件系统,存储系统启动以来的信息。当系统重启时,这个目录下的文件应该被删掉或清除。如果你的系统上有 /var/run 目录,应该让它指向 run。

2、Linux命令

2.1 cpuinfo

cat /proc/cpuinfo | grep -i processor

查看CPU型号:

cat /proc/cpuinfo | grep name | cut -f2 -d: | uniq -c

查看物理CPU个数:

cat /proc/cpuinfo| grep "physical id"| sort| uniq| wc -l

查看CPU核心数:

cat /proc/cpuinfo| grep "cpu cores"| uniq

查看逻辑CPU个数:

cat /proc/cpuinfo| grep "processor"| wc -l

lscpu

2.2 upower

upower 命令预装在大多数的 Linux 发行版本中。为了使用 upower 命令来展示电池的状态,打开终端并运行如下命令:

man upower

upower -e

upower -i /org/freedesktop/UPower/devices/battery_BAT0

upower -i `upower -e | grep 'BAT'`

upower -i $(upower -e | grep BAT) | grep --color=never -E "state|to\ full|to\ empty|percentage"

2.3 acpi

acpi 命令可以用来显示你的 Linux 发行版本中电池的状态以及其他 ACPI 信息。 在某些 Linux 发行版本中,你可能需要安装 acpi 命令。

https://github.com/torvalds/linux/blob/master/drivers/acpi/battery.c https://github.com/Juve45/batstat

## Debian、 Ubuntu 及其衍生版本中安装它

sudo apt-get install acpi

## RHEL、 CentOS、 Fedora 等系统中使用

sudo yum install acpi

sudo dnf install acpi

## 在 Arch Linux 及其衍生版本中使用

sudo pacman -S acpi

man acpi

acpi -V

acpi -a

cat /sys/class/power_supply/BAT0/uevent

cat /sys/class/power_supply/BAT0/capacity

find /sys/class/power_supply/BAT0/ -type f | xargs -tn1 cat

2.4 ps

ps

## ps命令查看所有进程

ps -aux

## ps命令查看具体某一应用的所有进程

## 查看chrome 的所有进程

ps -aux|grep chrome

## top命令当前时刻系统正在运行的所有进程

top

2.5 kill

kill (pid号)

killall (program应用名称)

pkill (program应用名称)

## 针对奔溃的窗口进程,无法退出、关闭,无法通过kill进程来终止

xkill

2.6 /proc/version

cat /proc/version

uname -a 查看系统内核版本号及系统名称

uname --s 显示内核名字

uname --r 显示内核版本

uname --n 显示网络主机名

uname --p 显示cpu

uname --m 如果显示i686,则表示安装了32位操作系统,如果显示 x86_64,则表示安装了64位操作系统

lsb_release -a

cat /etc/lsb-release

hostnamectl

cat /etc/os-release

cat /etc/issue

which gcc

gcc -v

getconf LONG_BIT

# 显示系统运行时间

uptime

2.7 ip

hostname -I

ip addr show | grep "inet"

/sbin/ifconfig | grep "inet addr"

2.8 filezilla

sudo apt-get update

sudo apt-get install filezilla

sudo apt-get install filezilla-locales

sudo chmod -R 777 myapp

./myapp

2.9 vim

# 键入:或/然后按上下箭头来选择某个历史命令

:w 保存文件但不退出vi

:w file 将修改另外保存到file中,不退出vi

:w! 强制保存,不推出vi

:wq 保存文件并退出vi

:wq! 强制保存文件,并退出vi

:q 不保存文件,退出vi

:q! 不保存文件,强制退出vi

:e! 放弃所有修改,从上次保存文件开始再编辑命令历史

2.10 meminfo(内存)

查看内存信息:

free -m

cat /proc/meminfo

查看内存硬件信息:

dmidecode -t memory

2.11 lsblk(磁盘)

查看硬盘和分区分布:

lsblk

查看硬盘和分区的详细信息:

fdisk -l

查看硬盘:

cat /proc/partitions

2.12 lspci(网卡)

查看网卡硬件信息:

lspci | grep -i 'eth'

# or

dmesg | grep -i eth

查看系统的所有网络接口:

ifconfig -a

ip link show

cat /proc/net/dev

如果要查看某个网络接口的详细信息,例如eth0的详细参数和指标:

ethtool eth0

ip a

查看MAC:

ip link show |grep 'link/ether'

2.13 lspci(主板)

查看pci信息,即主板所有硬件槽信息:

lspci

如果要更详细的信息:

lspci -v

# or

lspci -vv

如果要看设备树:

lspci -t

2.14 usb

查看usb信息:

lsusb

查看系统中的USB拓扑:

lsusb -t

lsusb -v

cat /sys/kernel/debug/usb/devices

cat /var/lib/usbutils/usb.ids | grep King

2.15 lsscsi

可以看到SCSI信息和所有虚拟磁盘以及光驱的信息:

sudo apt install lsscsi

lsscsi

2.16 bios

查看bios信息:

sudo dmidecode -t bios

sudo dmidecode -q

ls -l /sys/class/dmi/id/bios_*

2.17 dmidecode

# 查看处理器的信息

sudo dmidecode -t processor

# 查看内存的信息

sudo dmidecode -t memory

# 查看bios的信息

sudo dmidecode -t bios

# CPU ID

sudo dmidecode -t 4 | grep ID

# 主板序列号

sudo dmidecode -t 2 | grep Serial

# MAC地址

sudo lshw -c network | grep serial | head -n 1

2.18 lshw

查看所有硬件摘要信息:

lshw

可以查看所有硬件摘要信息,并输出成一个html文件:

lshw -html > /hardware.html

2.19 hwinfo

安装这个应用如下:

sudo apt install hwinfo

看看这个命令有些什么参数:

hwifo --help

看看cpu的信息:

hwinfo --cpu

3、Linux开发C/C++

3.1 gcc

gcc --version

3.2 g++

g++ --version

3.3 例子1:fopen

编写代码如下:

test_systeminfo.c

#include

#include

#include

#include

void getOsInfo()

{

FILE *fp = fopen("/proc/version", "r");

if(NULL == fp) {

printf("failed to open version\n");

return;

}

char szTest[4095] = {0};

while(!feof(fp))

{

memset(szTest, 0, sizeof(szTest));

fgets(szTest, sizeof(szTest) - 1, fp);

printf("%s", szTest);

}

fclose(fp);

}

void getCpuInfo()

{

FILE *fp = fopen("/proc/cpuinfo", "r");

if(NULL == fp) {

printf("failed to open cpuinfo\n");

return;

}

char szTest[1000] = {0};

// read file line by line

while(!feof(fp))

{

memset(szTest, 0, sizeof(szTest));

fgets(szTest, sizeof(szTest) - 1, fp);

printf("%s", szTest);

}

fclose(fp);

}

void getMemoryInfo()

{

FILE *fp = fopen("/proc/meminfo", "r");

if(NULL == fp) {

printf("failed to open meminfo\n");

return;

}

char szTest[1000] = {0};

while(!feof(fp))

{

memset(szTest, 0, sizeof(szTest));

fgets(szTest, sizeof(szTest) - 1, fp);

printf("%s", szTest);

}

fclose(fp);

}

int main(int argc, char **argv)

{

printf("===os information===\n");

getOsInfo();

printf("===cpu infomation===\n");

getCpuInfo();

printf("===memory information===\n");

getMemoryInfo();

return 0;

}

命令行输入命令:

g++ test_systeminfo.c -o test

# or

gcc test_systeminfo.c -o test

./test

# 查看文件信息,包含32-bit就是32位,包含64-bit就是64位

file test

3.4 例子2:pipe

linux使用dmidecode代码获取主板序列号:

#include

#include

#include

#include

int main(int argc, char *argv[])

{

pid_t pid;

int ret = 0;

int fd[2] = {0};

/* 创建管道 */

ret = pipe(fd);

if (ret == -1)

{

perror("pipe");

_exit(1);

}

/* 创建子进程,目的 1exec 2复制管道文件描述符 */

pid = vfork();

if (pid < 0)

{

perror("vfork");

}

else if (pid == 0)

{

dup2(fd[1], 1); /* 标准输出重定向到管道的写端 */

char str[50] = "sudo dmidecode -s system-serial-number";

execlp("/bin/sh", "sh", "-c", str, NULL);

}

else

{

char result[100] = "";

read(fd[0], result, sizeof(result)); /* 从管道的读端读取数据 */

char msg[100] = "";

sprintf(msg, "%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c:%c%c",

result[7], result[8], result[10], result[11], result[13], result[14], result[16], result[17],

result[19], result[20], result[22], result[23], result[25],

result[26], result[28], result[29], result[31], result[32],

result[34], result[35], result[37], result[38], result[40],

result[41], result[43], result[44], result[46], result[47],

result[49], result[50], result[52], result[53]);

printf("---->%s\n", msg);

}

return (0);

}

3.5 例子3:system

#include

#include

#include

#include

#include

#include

#include

static void parse_cpu_id(const char * file_name, const char * match_words, std::string & cpu_id)

{

cpu_id.c_str();

std::ifstream ifs(file_name, std::ios::binary);

if (!ifs.is_open())

{

return;

}

char line[4096] = { 0 };

while (!ifs.eof())

{

ifs.getline(line, sizeof(line));

if (!ifs.good())

{

break;

}

const char * cpu = strstr(line, match_words);

if (NULL == cpu)

{

continue;

}

cpu += strlen(match_words);

while ('\0' != cpu[0])

{

if (' ' != cpu[0])

{

cpu_id.push_back(cpu[0]);

}

++cpu;

}

if (!cpu_id.empty())

{

break;

}

}

ifs.close();

}

static bool get_cpu_id_by_system(std::string & cpu_id)

{

cpu_id.c_str();

const char * dmidecode_result = ".dmidecode_result.txt";

char command[512] = { 0 };

snprintf(command, sizeof(command), "sudo dmidecode -t 4 | grep ID > %s", dmidecode_result);

if (0 == system(command))

{

parse_cpu_id(dmidecode_result, "ID:", cpu_id);

}

unlink(dmidecode_result);

return(!cpu_id.empty());

}

int main(int argc, char* argv[])

{

std::string cpu_id;

get_cpu_id_by_system(cpu_id);

printf("%s\n", cpu_id.c_str());

return(0);

}

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

bool get_mac_address_by_ioctl(std::string & mac_address)

{

mac_address.clear();

int sock = socket(AF_INET, SOCK_STREAM, 0);

if (sock < 0)

{

return(false);

}

struct ifreq ifr = { 0 };

strncpy(ifr.ifr_name, "eth0", sizeof(ifr.ifr_name) - 1);

bool ret = (ioctl(sock, SIOCGIFHWADDR, &ifr) >= 0);

close(sock);

const char hex[] =

{

'0', '1', '2', '3', '4', '5', '6', '7',

'8', '9', 'a', 'b', 'c', 'd', 'e', 'f'

};

char mac[16] = { 0 };

for (int index = 0; index < 6; ++index)

{

size_t value = ifr.ifr_hwaddr.sa_data[index] & 0xFF;

mac[2 * index + 0] = hex[value / 16];

mac[2 * index + 1] = hex[value % 16];

}

std::string(mac).swap(mac_address);

return(ret);

}

static void parse_mac_address(const char * file_name, const char * match_words, std::string & mac_address)

{

mac_address.c_str();

std::ifstream ifs(file_name, std::ios::binary);

if (!ifs.is_open())

{

return;

}

char line[4096] = { 0 };

while (!ifs.eof())

{

ifs.getline(line, sizeof(line));

if (!ifs.good())

{

break;

}

const char * mac = strstr(line, match_words);

if (NULL == mac)

{

continue;

}

mac += strlen(match_words);

while ('\0' != mac[0])

{

if (' ' != mac[0] && ':' != mac[0])

{

mac_address.push_back(mac[0]);

}

++mac;

}

if (!mac_address.empty())

{

break;

}

}

ifs.close();

}

static bool get_mac_address_by_system(std::string & mac_address)

{

mac_address.c_str();

const char * lshw_result = ".lshw_result.txt";

char command[512] = { 0 };

snprintf(command, sizeof(command), "lshw -c network | grep serial | head -n 1 > %s", lshw_result);

if (0 == system(command))

{

parse_mac_address(lshw_result, "serial:", mac_address);

}

unlink(lshw_result);

return(!mac_address.empty());

}

int main(int argc, char * argv[])

{

std::string mac_address1;

get_mac_address_by_ioctl(mac_address1);

printf("get_mac_address_by_ioctl: %s\n", mac_address1.c_str());

std::string mac_address2;

get_mac_address_by_system(mac_address2);

printf("get_mac_address_by_system: %s\n", mac_address2.c_str());

return(0);

}

3.6 例子4:std::ifstream

#include

#include

#include

int main()

{

std::string cpu;

std::ifstream readCPU;

long luser, lnice, lsys, lidle, liowait, lirq, lsoftirq, ltotal;

readCPU.open("/proc/stat", std::ifstream::in);

readCPU >> cpu >> luser >> lnice >> lsys >> lidle >> liowait >> lirq >> lsoftirq;

ltotal = luser + lnice + lsys + lidle + liowait + lirq + lsoftirq;

readCPU.close();

while (true)

{

sleep(2);

long user, nice, sys, idle, iowait, irq, softirq, total;

readCPU.open("/proc/stat", std::ifstream::in);

readCPU >> cpu >> user >> nice >> sys >> idle >> iowait >> irq >> softirq;

readCPU.close();

total = user + nice + sys + idle + iowait + irq + softirq;

long usage = static_cast(static_cast(total - ltotal - (idle - lidle)) / static_cast(total - ltotal) * 100);

std::cout << "CPU使用率: " << usage << " %" << std::endl;

luser = user;

lnice = nice;

lsys = sys;

lidle = idle;

liowait = iowait;

lirq = irq;

lsoftirq = softirq;

ltotal = total;

}

}

#include

#include

#include

int main()

{

std::ifstream cpuTemp;

long temp;

while (true)

{

cpuTemp.open("/sys/class/thermal/thermal_zone0/temp", std::ifstream::in);

cpuTemp >> temp;

std::cout << "CPU温度为: " << static_cast(temp) / 1000 << std::endl;

cpuTemp.close();

sleep(1);

}

}

3.7 例子5:popen

#include

#include

#include

#include

#include

#include

void get_cmdstr(const char *cmd, std::string& ret)

{

char result[10240] = {0};

char buf[1024] = {0};

FILE *fp = NULL;

if( (fp = popen(cmd, "r")) == NULL ) {

printf("popen error!\n");

return;

}

while (fgets(buf, sizeof(buf), fp)) {

strcat(result, buf);

}

pclose(fp);

printf("result: %s\n", result);

std::string code_ = std::string(result);

ret = std::string(result);

}

int main()

{

std::string ret;

get_cmdstr("cat /proc/version", ret);

printf("%s\n", ret.c_str());

}

#include

#include

#define CMD_RESULT_BUF_SIZE 1024

/*

* cmd:待执行命令

* result:命令输出结果

* 函数返回:0 成功;-1 失败;

*/

int ExecuteCMD(const char *cmd, char *result)

{

int iRet = -1;

char buf_ps[CMD_RESULT_BUF_SIZE];

char ps[CMD_RESULT_BUF_SIZE] = {0};

FILE *ptr;

strcpy(ps, cmd);

if((ptr = popen(ps, "r")) != NULL)

{

while(fgets(buf_ps, sizeof(buf_ps), ptr) != NULL)

{

strcat(result, buf_ps);

if(strlen(result) > CMD_RESULT_BUF_SIZE)

{

break;

}

}

pclose(ptr);

ptr = NULL;

iRet = 0; // 处理成功

}

else

{

printf("popen %s error\n", ps);

iRet = -1; // 处理失败

}

return iRet;

}

std::string SystemWithResult(const char *cmd)

{

char cBuf[CMD_RESULT_BUF_SIZE] = {0};

string sCmdResult;

ExecuteCMD(cmd, cBuf);

sCmdResult = string(cBuf);

printf("CMD Result: \n%s\n", sCmdResult.c_str());

return sCmdResult;

}

结语

如果您觉得该方法或代码有一点点用处,可以给作者点个赞,或打赏杯咖啡;╮( ̄▽ ̄)╭ 如果您感觉方法或代码不咋地//(ㄒoㄒ)//,就在评论处留言,作者继续改进;o_O??? 如果您需要相关功能的代码定制化开发,可以留言私信作者;(✿◡‿◡) 感谢各位大佬童鞋们的支持!( ´ ▽´ )ノ ( ´ ▽´)っ!!!

查看原文