C语言获取硬件信息(CPU序列号,硬盘序列号,网卡IPMAC地址是否插入网线)
Posted 叶落花枯
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了C语言获取硬件信息(CPU序列号,硬盘序列号,网卡IPMAC地址是否插入网线)相关的知识,希望对你有一定的参考价值。
目录
一、前言
本文主要介绍Linux和Windows下使用C语言获取各种硬件信息,包括CPU序列号、硬盘序列号、网卡信息(包括网卡名字、IP地址、MAC地址、网卡是否插入网线等)。
二、代码实现
Linux下所需包含的头文件
#include <linux/hdreg.h>
#include <fcntl.h>
#include <stdlib.h>
#include <ctype.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <net/if.h>
#include <unistd.h>
#include <sys/io.h>
#include <arpa/inet.h>
#include <string.h>
#include <stdio.h>
#include <sys/ioctl.h>
Windows下所需包含的头文件
#include <iostream>
#include <string>
#include <windows.h>
#include <iphlpapi.h>
2.1 获取CPU序列号
- Linux下获取CPU序列号,也就是id,经过实测发现,相同厂家相同型号的CPU的序列号是一样的。
/**
* @brief getCpuId 获取Linux下的CPU序列号
* @param id 存储获取到的CPU序列号的字符串变量
* @return 0:获取成功 其他返回值:获取失败
*/
int getCpuId(char *id)
unsigned int s1,s2;
asm volatile
( "movl $0x01,%%eax ; \\n\\t"
"xorl %%edx,%%edx ;\\n\\t"
"cpuid ;\\n\\t"
"movl %%edx , %0;\\n\\t"
"movl %%eax , %1;\\n\\t"
:"=m"(s1),"=m"(s2)
);
if(0 == s1 && 0 == s2)
return -1;
char cpu_id[32] = 0;
sprintf(cpu_id, "%08X-%08X", htonl(s2), htonl(s1));
strcpy(id, cpu_id);
return 0;
- Windows下获取CPU序列号,也就是id,经过实测发现,相同厂家相同型号的CPU的序列号是一样的。
/**
* @brief GetCpuByCmd 获取windows下的CPU序列号
* @param ider 获取到的CPU序列号的字符串变量
* @return true:获取成功 false:获取失败
*/
bool GetCpuByCmd(string &ider)
//CPU序列号
const long MAX_COMMAND_SIZE = 64; //命令行输出缓冲大小
WCHAR szFetCmd[] = L"wmic cpu get processorid"; //获取CPU序列号命令行
const string strEnSearch = "ProcessorId"; //CPU序列号前导信息
BOOL bret = FALSE;
HANDLE hReadPipe = NULL; //读取管道
HANDLE hWritePipe = NULL; //写入管道
PROCESS_INFORMATION pi; //进程信息
STARTUPINFO si; //控制命令行窗口信息
SECURITY_ATTRIBUTES sa; //安全属性
char szBuffer[MAX_COMMAND_SIZE + 1] = 0; //放置命令行结果的输出缓存区
string strBuffer;
unsigned long count = 0;
long ipos = 0;
memset(&pi , 0 , sizeof(pi));
memset(&si , 0 , sizeof(si));
memset(&sa , 0 , sizeof(sa));
//初始化管道
pi.hProcess = NULL;
pi.hThread = NULL;
si.cb = sizeof(STARTUPINFO);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
//创建管道
bret = CreatePipe(&hReadPipe , &hWritePipe , &sa , 0);
if(!bret)
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//设置命令行窗口的信息为指定的读写管道
GetStartupInfo(&si);
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
si.wShowWindow = SW_HIDE; //隐藏命令行窗口
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//创建获取命令行的进程
bret = CreateProcess(NULL , szFetCmd , NULL , NULL , TRUE , 0 , NULL , NULL , &si , &pi);
if(!bret)
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//读取返回的数据
WaitForSingleObject(pi.hProcess , 500);
bret = ReadFile(hReadPipe , szBuffer , MAX_COMMAND_SIZE , &count , 0);
if(!bret)
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//查找CPU序列号
bret = FALSE;
strBuffer = szBuffer;
ipos = strBuffer.find(strEnSearch);
if(ipos < 0) //没有找到
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
else
strBuffer = strBuffer.substr(ipos + strEnSearch.length());
memset(szBuffer , 0x00 , sizeof(szBuffer));
strcpy_s(szBuffer , strBuffer.c_str());
//去掉中间的空格\\r\\n
char temp[512];
memset(temp , 0 , sizeof(temp));
int index = 0;
for(size_t i = 0 ; i < strBuffer.size() ; i++)
if(strBuffer[i] != ' ' && strBuffer[i] != '\\n' && strBuffer[i] != '\\r')
temp[index] = strBuffer[i];
index++;
ider = temp;
return true;
2.2 获取硬盘序列号
- Linux下获取硬盘序列号。
/**
* @brief removeBlank 删除字符串中的空格
* @param str 需要处理的字符串
* @return 无返回值
*/
void removeBlank(char *str)
char *str_c = str;
int i,j=0;
for(i=0;str[i]!='\\0';i++)
if(str[i]!=' ')
str_c[j++]=str[i];
str_c[j]='\\0';
str = str_c;
/**
* @brief getDiskId 获取Linux下的硬盘序列号
* @param hd_name 硬盘所在位置 例:/dev/sda
* @param id 存储获取到的硬盘序列号的字符串变量
* @return 0:获取成功 其他返回值:获取失败
*/
int getDiskId(char *hd_name, char *id)
struct hd_driveid hid;
int fd = open(hd_name,O_RDONLY | O_NONBLOCK);
if(fd <0)
perror("open fd");
return -1;
if(ioctl(fd,HDIO_GET_IDENTITY,&hid)<0)
perror("ioctl");
return -1;
close(fd);
char disk_id[32] = 0;
sprintf(disk_id, "%s", hid.serial_no);
removeBlank(disk_id); //删除字符串中的空格
strcpy(id, disk_id);
return 0;
- Windows下获取硬盘序列号。
/**
* @brief GetDiskByCmd 获取windows下的硬盘序列号
* @param ider 获取到的硬盘序列号的字符串变量
* @return true:获取成功 false:获取失败
*/
bool GetDiskByCmd(string &ider)
//硬盘序列号
const long MAX_COMMAND_SIZE = 64; //命令行输出缓冲大小
WCHAR szFetCmd[] = L"wmic diskdrive get serialnumber"; //获取CPU序列号命令行
const string strEnSearch = "SerialNumber"; //CPU序列号前导信息
BOOL bret = FALSE;
HANDLE hReadPipe = NULL; //读取管道
HANDLE hWritePipe = NULL; //写入管道
PROCESS_INFORMATION pi; //进程信息
STARTUPINFO si; //控制命令行窗口信息
SECURITY_ATTRIBUTES sa; //安全属性
char szBuffer[MAX_COMMAND_SIZE + 1] = 0; //放置命令行结果的输出缓存区
string strBuffer;
unsigned long count = 0;
long ipos = 0;
memset(&pi, 0, sizeof(pi));
memset(&si, 0, sizeof(si));
memset(&sa, 0, sizeof(sa));
//初始化管道
pi.hProcess = NULL;
pi.hThread = NULL;
si.cb = sizeof(STARTUPINFO);
sa.nLength = sizeof(SECURITY_ATTRIBUTES);
sa.lpSecurityDescriptor = NULL;
sa.bInheritHandle = TRUE;
//创建管道
bret = CreatePipe(&hReadPipe, &hWritePipe, &sa, 0);
if(!bret)
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//设置命令行窗口的信息为指定的读写管道
GetStartupInfo(&si);
si.hStdError = hWritePipe;
si.hStdOutput = hWritePipe;
si.wShowWindow = SW_HIDE; //隐藏命令行窗口
si.dwFlags = STARTF_USESHOWWINDOW | STARTF_USESTDHANDLES;
//创建获取命令行的进程
bret = CreateProcess(NULL, szFetCmd, NULL, NULL, TRUE, 0, NULL, NULL, &si, &pi);
if(!bret)
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//读取返回的数据
WaitForSingleObject(pi.hProcess , 500);
bret = ReadFile(hReadPipe, szBuffer, MAX_COMMAND_SIZE, &count, 0);
if(!bret)
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
//查找CPU序列号
bret = FALSE;
strBuffer = szBuffer;
ipos = strBuffer.find(strEnSearch);
if(ipos < 0) //没有找到
CloseHandle(hWritePipe);
CloseHandle(hReadPipe);
CloseHandle(pi.hProcess);
CloseHandle(pi.hThread);
else
strBuffer = strBuffer.substr(ipos + strEnSearch.length());
memset(szBuffer, 0x00, sizeof(szBuffer));
strcpy_s(szBuffer, strBuffer.c_str());
//去掉中间的空格\\r\\n
char temp[512];
memset(temp , 0 , sizeof(temp));
int index = 0;
for(size_t i = 0; i < strBuffer.size(); i++)
if(strBuffer[i] != ' ' && strBuffer[i] != '\\n' && strBuffer[i] != '\\r')
temp[index] = strBuffer[i];
index++;
ider = temp;
return true;
2.3 获取网卡信息
- Linux下获取网卡信息,包括网卡名字、IP地址、MAC地址、是否已经插入网线等信息。
//网卡信息结构体1
typedef struct __net_iface
int sum_n;
char net_name1[20];
char net_name2[20];
char net_name3[20];
char net_name4[20];
char net_name5[20];
char net_ip1[16];
char net_ip2[16];
char net_ip3[16];
char net_ip4[16];
char net_ip5[16];
char net_mac1[32];
char net_mac2[32];
char net_mac3[32];
char net_mac4[32];
char net_mac5[32];
net_iface;
//网卡信息结构体2
struct net_iface_1
struct net_iface_1 *next; //指向下一个网卡信息结构体的地址
char net_name[20]; //网卡名字
char net_ip[16]; //网卡IP
;
/**
* @brief get_iface_name 获取网口名字
* @param get_iface OUT 结构体
* @return 成功返回1 错误返回负数
*/
int get_iface_name(net_iface *get_iface)
int sock_get_iface;
struct ifconf ifc_get_iface;
struct ifreq *ifr_get_iface;
//初始化 ifconf
char buf[512];
ifc_get_iface.ifc_len = 512;
ifc_get_iface.ifc_buf = buf;
memset(get_iface,0,sizeof(net_iface));
sock_get_iface = socket(AF_INET,SOCK_DGRAM,0);
if(sock_get_iface < 0)
perror("SOCKET:");
return -1;
if(ioctl(sock_get_iface ,SIOCGIFCONF,&ifc_get_iface) < 0)
perror("ioctl");
return -1;
ifr_get_iface = (struct ifreq*)buf;
get_iface->sum_n = ifc_get_iface.ifc_len/sizeof(struct ifreq);
int control_n = 1;
for(int i = (ifc_get_iface.ifc_len/sizeof(struct ifreq)); i > 0; i--)
if(strcmp(inet_ntoa(((struct sockaddr_in*)&(ifr_get_iface->ifr_addr))->sin_addr),"127.0.0.1") == 0)
ifr_get_iface++;
get_iface->sum_n--;
continue;
else
switch (control_n)<以上是关于C语言获取硬件信息(CPU序列号,硬盘序列号,网卡IPMAC地址是否插入网线)的主要内容,如果未能解决你的问题,请参考以下文章
Python获取电脑硬件配置的封装类,可以获取CPU序列号主板序列号BIOS序列号硬盘序列号和网卡MAC地址
Python获取电脑CPU序列号主板序列号BIOS序列号硬盘序列号列表网卡MAC地址
windows x下的c编程,获取电脑硬件序列号(cpu 硬盘 bios 主版)!很着急!邮箱wangyu850722@163.com