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序列号

  1. 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;

  1. 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 获取硬盘序列号

  1. 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;

  1. 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 获取网卡信息

  1. 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地址

用C语言怎么得到电脑的CPU序列号,硬盘序列号等信息

windows x下的c编程,获取电脑硬件序列号(cpu 硬盘 bios 主版)!很着急!邮箱wangyu850722@163.com

使用WMI编程获取主机硬件信息(CPU_ID,硬盘主板BIOS序列号,Mac地址)

获取网卡MAC硬盘序列号CPU_IDBIOS编号