Halcom 发表于 2022-3-16 21:20:26

windows操作系统mac地址获取

windows操作系统mac地址获取
// ConsoleApplication1.cpp: 定义控制台应用程序的入口点。
//
#include "stdafx.h"
#include <windows.h>
#include <iphlpapi.h>       // API GetAdaptersInfo 头文件
#include <shlwapi.h>      // API StrCmpIA 头文件
#pragma comment(lib, "iphlpapi.lib")
#pragma comment(lib, "shlwapi.lib")
#include <Strsafe.h>      // API StringCbPrintfA 头文件
#include <shellapi.h>       // API lstrcpyA 头文件
#include <iostream>
#define MAX_SIZE 50
#define BUF_SIZE 50

//
// 功能:获取适配器特性
// 参数:
//   adapter_name 适配器 ID
// 返回值:成功则返回由参数指定的适配器的特性标志,是一个 DWORD 值,失败返回 0
//
UINT GetAdapterCharacteristics(char* adapter_name)
{
      if (adapter_name == NULL || adapter_name == 0)
                return 0;

      HKEY root = NULL;
      // 打开存储适配器信息的注册表根键
      if (ERROR_SUCCESS != RegOpenKeyExA(HKEY_LOCAL_MACHINE, "SYSTEM\\CurrentControlSet\\Control\\Class\\{4D36E972-E325-11CE-BFC1-08002BE10318}", 0, KEY_READ, &root))
                return 0;

      DWORD subkeys = 0;
      // 获取该键下的子键数
      if (ERROR_SUCCESS != RegQueryInfoKeyA(root, NULL, NULL, NULL, &subkeys, NULL, NULL, NULL, NULL, NULL, NULL, NULL))
                subkeys = 100;

      DWORD ret_value = 0;
      for (DWORD i = 0; i < subkeys; i++)
      {
                // 每个适配器用一个子键存储,子键名为从 0 开始的 4 位数
                char subkey;
                memset(subkey, 0, MAX_SIZE);
                StringCbPrintfA(subkey, MAX_SIZE, "%04u", i);

                // 打开该子键
                HKEY hKey = NULL;
                if (ERROR_SUCCESS != RegOpenKeyExA(root, subkey, 0, KEY_READ, &hKey))
                        continue;

                // 获取该子键对应的适配器 ID,存于 name 中
                char name;
                DWORD type = 0;
                DWORD size = MAX_PATH;
                if (ERROR_SUCCESS != RegQueryValueExA(hKey, "NetCfgInstanceId", NULL, &type, (LPBYTE)name, &size))
                {
                        RegCloseKey(hKey);
                        continue;
                }

                // 对比该适配器 ID 是不是要获取特性的适配器 ID
                if (StrCmpIA(name, adapter_name) != 0)
                {
                        RegCloseKey(hKey);
                        continue;
                }

                // 读取该适配器的特性标志,该标志存储于值 Characteristics 中
                DWORD val = 0;
                size = 4;
                LSTATUS ls = RegQueryValueExA(hKey, "Characteristics", NULL, &type, (LPBYTE)&val, &size);
                RegCloseKey(hKey);

                if (ERROR_SUCCESS == ls)
                {
                        ret_value = val;
                        break;
                }
      }

      RegCloseKey(root);
      return ret_value;
}

//
// 功能:获取 Mac 地址的二进制数据
// 参数:
//   mac 用于输出 Mac 地址的二进制数据的缓冲区指针
// 返回值:成功返回 mac 地址的长度,失败返回 0,失败时 mac 中保存一些简单的错误信息,可适当修改,用于调试
//
int GetMAC(BYTE mac)
{
#define NCF_PHYSICAL 0x4
      DWORD AdapterInfoSize = 0;
      if (ERROR_BUFFER_OVERFLOW != GetAdaptersInfo(NULL, &AdapterInfoSize))
      {
                StringCbPrintfA((LPSTR)mac, BUF_SIZE, "GetMAC Failed! ErrorCode: %d", GetLastError());
                return 0;
      }

      void* buffer = malloc(AdapterInfoSize);
      if (buffer == NULL)
      {
                lstrcpyA((LPSTR)mac, "GetMAC Failed! Because malloc failed!");
                return 0;
      }

      PIP_ADAPTER_INFO pAdapt = (PIP_ADAPTER_INFO)buffer;
      if (ERROR_SUCCESS != GetAdaptersInfo(pAdapt, &AdapterInfoSize))
      {
                StringCbPrintfA((LPSTR)mac, BUF_SIZE, "GetMAC Failed! ErrorCode: %d", GetLastError());
                free(buffer);
                return 0;
      }

      int mac_length = 0;
      while (pAdapt)
      {
                if (pAdapt->AddressLength >= 6 && pAdapt->AddressLength <= 8)
                {
                        memcpy(mac, pAdapt->Address, pAdapt->AddressLength);
                        mac_length = pAdapt->AddressLength;

                        UINT flag = GetAdapterCharacteristics(pAdapt->AdapterName);
                        bool is_physical = ((flag & NCF_PHYSICAL) == NCF_PHYSICAL);
                        if (is_physical)
                              break;
                }
                pAdapt = pAdapt->Next;
      }
      free(buffer);
      return mac_length;
}

//
// 功能:获取 Mac 地址,使用时直接调用此函数即可
// 参数:
//   mac 用于存储 Mac 地址的缓冲区指针
// 返回值:无返回值,函数执行完后会把 Mac 地址以16进制的形式存于参数指定的缓冲区中,若有错误,缓冲区中保存的是错误信息
//
void GetMacAddress(char* mac)
{
      BYTE buf;
      memset(buf, 0, BUF_SIZE);

      int len = GetMAC(buf);
      if (len <= 0)
      {
                lstrcpyA(mac, (LPCSTR)buf);
                return;
      }

      if (len == 6)
                StringCbPrintfA(mac, BUF_SIZE, "%02X-%02X-%02X-%02X-%02X-%02X", buf, buf, buf, buf, buf, buf);
      else
                StringCbPrintfA(mac, BUF_SIZE, "%02X-%02X-%02X-%02X-%02X-%02X-%02X-%02X", buf, buf, buf, buf, buf, buf, buf, buf);
}

int main() {
      char str;
      GetMacAddress(str);
      std::cout << str << std::endl;
      std::cin.get();
}E0-D5-5E-A4-12-F5

参考:
【1】https://blog.csdn.net/m0_37811192/article/details/82216825


Halcom 发表于 2022-3-16 21:37:43

C#获取MAC地址
      public string getMacAddress()
      {
            string macAddress = null;
            try
            {
                NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
                foreach (NetworkInterface adapter in nics)
                {
                  if (adapter.NetworkInterfaceType.ToString().Equals("Ethernet")) //是以太网卡
                  {
                        string fRegistryKey = "SYSTEM\\CurrentControlSet\\Control\\Network\\{4D36E972-E325-11CE-BFC1-08002BE10318}\\" + adapter.Id + "\\Connection";
                        RegistryKey rk = Registry.LocalMachine.OpenSubKey(fRegistryKey, false);
                        if (rk != null)
                        {
                            // 区分 PnpInstanceID   
                            // 如果前面有 PCI 就是本机的真实网卡   
                            // MediaSubType 为 01 则是常见网卡,02为无线网卡。   
                            string fPnpInstanceID = rk.GetValue("PnpInstanceID", "").ToString();
                            int fMediaSubType = Convert.ToInt32(rk.GetValue("MediaSubType", 0));
                            if (fPnpInstanceID.Length > 3 && fPnpInstanceID.Substring(0, 3) == "PCI") //是物理网卡
                            {
                              macAddress = adapter.GetPhysicalAddress().ToString();
                              break;
                            }
                            else if (fMediaSubType == 1) //虚拟网卡
                              continue;
                            else if (fMediaSubType == 2) //无线网卡(上面判断Ethernet时已经排除了)
                              continue;
                        }
                  }
                }
            }
            catch
            {
                macAddress = null;
            }
            return macAddress;
      }
页: [1]
查看完整版本: windows操作系统mac地址获取