wmi获取禁用网卡的mac地址

wmi获取禁用网卡的mac地址

  • 最近遇到一个性能问题,我们的软件启动需要验证License,验证License需要获取网卡的mac地址(无论是禁用的还是启用的)。之前的做法是运行一个进程执行 chcp 437&&powershell Get-NetAdapter
    • 这相当于先开启一个cmd 执行 chcp 437 ,然后在cmd再启动 powershell 执行 Get-NetAdapter
    • 此操作相当耗时,基本上要耗时2秒以上,这对于软件启动来说是不可接受的
    • 所以就研究了 powershell执行的 Get-NetAdapter 底层是如何实现的,是否可以在 C# 中直接复刻实现以达到减少耗时的目的。

为什么采用启动powershell的方式去获取网卡的mac地址

  • 常用的获取网卡地址的方式

    1. NetworkInterface.GetAllNetworkInterfaces获取不到禁用的网卡信息

      csharp 复制代码
      var list = NetworkInterface.GetAllNetworkInterfaces();
      foreach (var item in list)
      {
          var name = item.Name;
          var address = item.GetPhysicalAddress();
          Debug.WriteLine($"name: {name}, mac: {address}");
      }
    2. 使用wmi方式获取 Win32_NetworkAdapter获取不到禁用网卡的Mac地址

      csharp 复制代码
      using (var search = new ManagementObjectSearcher("select * from Win32_NetworkAdapter where PhysicalAdapter = TRUE"))
      {
          foreach(ManagementObject item in search.Get())
          {
              string name = item["Name"]?.ToString();
              string address = item["MACAddress"]?.ToString();
              Debug.WriteLine($"name: {name}, mac: {address}");
          }
      }
  • 基于以上两种常用的方式都无法获取到禁用网卡的信息,故最后采用绕远路的方法:启动powershell执行 get-netadapter

powershell的 get-netadapter底层做了些什么?

  • 经过查阅资料,get-netadapter 其实是调用了 Get-CimInstance -Namespace root/StandardCimv2 -ClassName MSFT_NetAdapter
  • 于是兴冲冲的打开 powershell 执行了以上命令,结果输出的内容很多,与 get-netadapter 输出的内容大相径庭。
  • 但是在执行完一遍get-netadapter之后,再次运行 Get-CimInstance 命令,发现输出内容确实一致
    • 这里问了chatgpt,说是get-adapter 会做一些初始化的操作,如果先执行 get-ciminstance (在没有初始化的前提下),会输出一些不正确的内容。
  • get-ciminstance 命令其实就是调用的 wmi

什么是wmi

  • wmi: windows management instruments windows管理规范,提供了系统信息访问的api

  • 一句话总结:wmi=windows的系统级数据库,你可以通过wql语句查看和控制系统

  • 那cim又是什么东西?

    • wmi是基于 cim 实现的,common infomation model, 意思就是将系统资源抽象成类
    • 我们可以通过查询语句去访问这些资源类对象的信息
  • 微软将系统资源抽象成类,把这些类放在不同的命名空间下(默认的命名空间为root\CIMV2),并且将类的名称添加了前缀,具体划分规则如下

    类名前缀 来源 典型命名空间 举例
    Win32_ 传统 WMI 类(早期,兼容旧系统) root\CIMV2 Win32_Process, Win32_NetworkAdapter
    MSFT_ 新一代 CIM 类(基于 PowerShell 和 DMTF 标准) root\StandardCimv2 MSFT_NetAdapter, MSFT_Disk, MSFT_NetIPAddress
    CIM_ 标准 DMTF(跨平台)类 root\CIMV2 CIM_LogicalDisk, CIM_ComputerSystem
    自定义(厂商名) 第三方 / OEM 驱动提供 root\WMIroot\<vendor> Intel_SMBIOSData, Dell_BIOSProvider
  • windows界面的设备管理器有一部分的实现就是基于 wmi

类名 描述
Win32_Process 表示系统中的一个进程
Win32_Service 表示一个 Windows 服务
MSFT_NetAdapter 表示一个网络适配器
Win32_LogicalDisk 表示一个逻辑磁盘(C盘、D盘等)

如何使用wmi呢?

  • powershell
    • 访问 Win32_NetworkAdapter类对象: get-ciminstance -classname win32_networkadapter
  • C#: 上面已经讲过

解决方案

  • 既然已经知道powershell的命令get-netadapter 底层是 Get-CimInstance -Namespace root/StandardCimv2 -ClassName MSFT_NetAdapter,那么我们就可以应用到c#上
csharp 复制代码
using (var search = new ManagementObjectSearcher("root/standardcimv2", "select * from msft_netadapter"))
{
    foreach (ManagementObject item in search.Get())
    {
        string name = item["Name"]?.ToString();
        string address = item["MacAddress"]?.ToString();
        Debug.WriteLine($"name: {name}, mac: {address}");
    }
}
  • 但是!!!运行报错了 ,提示没有 MacAddress这个字段,又是经过了一番尝试,发现原来这里是 PermanentAddress,可能是powershell 为了显示的更准确,自行改了字段的名称

扩展

走的歪路:使用c++调用wmi获取系统信息

  • 之前做了很多尝试依旧不得入门,无法在C#中获取到禁用网卡的mac地址,于是转而让chatgpt给个c++的方案,虽然给的代码很多编译报错,运行报错,最后终于运行起来一次(连续运行第二次就崩溃),好歹成功获取到了,也就是这里发现读取的是 PermanentAddress 字段,而不是 MacAddress,最终找到了在C#中的正确方案。
    • 在得到正确方案后,也就没有再研究c++方案为什么运行第二次就会崩溃的问题,空下来再说(自我安慰,基本上是不会再去看那段代码了)
相关推荐
木心术15 小时前
Windows系统下MySQL与AI工具集成方案:数据存储与调用实践
人工智能·windows·mysql
beyond阿亮5 小时前
Hermes Agent快速接入 QQ 完整教程|QQ聊天使用AI智能体
人工智能·windows·ai·openclaw·hermes agent
DONSEE广东东信智能读卡器6 小时前
用PowerShell实现Windows 本地 WSS/HTTPS 自签名证书配置方法
windows·网络协议·https·powershell·身份证阅读器
DogDaoDao9 小时前
Windows 下 Git 报错:`touch` 无法识别 —— 原因分析与 7 种解决方案(从入门到精通)
windows·git·程序员·npm·powershell·cmd·touch
Ai.den10 小时前
Windows 安装 MinerU 3.x 实现本地批量解析 PDF
人工智能·windows·ai
xfddlm10 小时前
在Windows上配置Claude Code
windows
AI行业学习10 小时前
Notepad++ 下载+安装+插件集合 完整教程(Windows,安全无捆绑)
windows·notepad++
__zRainy__11 小时前
uni-app 全局容器实战系列(二):Vite 虚拟模块
windows·uni-app
Omics Pro11 小时前
前沿学科:量子生物学!
大数据·数据库·人工智能·windows·redis·量子计算
IceSugarJJ12 小时前
Windows下VSCode+ WSL项目启动流程
linux·windows·vscode·ubuntu·wsl