通过 WMI 确定网络适配器类型

Posted

技术标签:

【中文标题】通过 WMI 确定网络适配器类型【英文标题】:Determine Network Adapter Type via WMI 【发布时间】:2012-04-11 21:46:04 【问题描述】:

我正在使用 WMI (Win32_NetworkAdapter) 并尝试获取连接的有线或无线物理网络适配器的详细信息,并避免使用虚拟适配器等。

阅读this article 说明您必须对 WMI 进行一些巧妙的查询以消除虚拟适配器并尝试仅返回真实的物理适配器。

阅读this post它解释说,您可以比较网络适配器的“描述”中的文本,看看它是否包括“无线”、“802.11”或“WLAN”,如果有,那么很可能是adapter 是一个无线适配器。

随着今天的 .Net 版本和其他改进,在 Windows XP+ 上确定网络适配器是有线还是无线以及不是来自 VM 软件或类似软件的虚拟适配器真的只有这两种方法吗?如果不是,请解释。

【问题讨论】:

您只是在寻找涉及 WMI 的解决方案吗? 最好,是的。我现有的项目非常广泛地使用 WMI 和 .Net 来获取适配器信息。如果还有其他选择,我想知道但不确定是否会实施。 使用 WMI 不能只根据Win32_NetworkAdapter.PhysicalAdapter 过滤(如果接口是虚拟的,应该是假的)然后使用AdapterTypeID 来确定它是有线还是无线?我浏览了您发布的文章,他们的标准不合理。 msdn.microsoft.com/en-us/library/windows/desktop/…Win32_NetworkAdapter.PhysicalAdapter Windows Server 2003、Windows XP、Windows 2000 和 Windows NT 4.0:此属性不可用。 AdapterTypeID 不可靠,因为我的笔记本电脑在这里,WMI 将其返回为非无线。 【参考方案1】:

您可以在 'root\StandardCimv2' 命名空间中使用新的 WMI 类 MSFT_NetAdapterWindows 8 中引入了此类。

我们可以使用属性 ConnectorPresent 仅过滤到物理适配器。 接下来我们必须消除 Wi-Fi 适配器(存在于物理适配器中),我们可以使用 InterfaceType 和/或 NdisPhysicalMedium 属性。

InterfaceType 由 Internet 名称分配机构 (IANA) 定义,对于所有类似以太网的接口,其值为 ethernetCsmacd (6)(请参阅 https://www.iana.org/assignments/ianaiftype-mib/ianaiftype-mib)。

NdisPhysicalMedium 中用于以太网适配器值 0802.3 (14)

所以我在 C# 中的解决方案是:

try

    var objectSearcher = new ManagementObjectSearcher("root\\StandardCimv2", $@"select Name, InterfaceName, InterfaceType, NdisPhysicalMedium from MSFT_NetAdapter where ConnectorPresent=1"); //Physical adapter

    int count = 0;
    foreach (var managementObject in objectSearcher.Get())
    
        //The locally unique identifier for the network interface. in InterfaceType_NetluidIndex format. Ex: Ethernet_2.
        string interfaceName = managementObject["InterfaceName"]?.ToString();
        //The interface type as defined by the Internet Assigned Names Authority (IANA).
        //https://www.iana.org/assignments/ianaiftype-mib/ianaiftype-mib
        UInt32 interfaceType = Convert.ToUInt32(managementObject["InterfaceType"]);
        //The types of physical media that the network adapter supports.
        UInt32 ndisPhysicalMedium = Convert.ToUInt32(managementObject["NdisPhysicalMedium"]);

        if (!string.IsNullOrEmpty(interfaceName) &&
            interfaceType == 6 &&       //ethernetCsmacd(6) --for all ethernet-like interfaces, regardless of speed, as per RFC3635
            (ndisPhysicalMedium == 0 || ndisPhysicalMedium == 14))   //802.3
        
            count++;
        
    

    return count;

catch (ManagementException)

    //Run-time requirements WMI MSFT_NetAdapter class is included in Windows 8 and Windows Server 2012

【讨论】:

这很好。谢谢你。太糟糕了,我们仍然在我们所有的设备上使用 Windows 7 Embedded :( @HolaJan 我们是否也可以将上面的代码移植到 C++ 中(除了 C# 结构)?我的意思是要知道是否有另一个 C++ 库/DLL 实例化相同的管理对象实例和对象搜索机制。【参考方案2】:

我知道这是一个老问题,但我在互联网上有found an answer elsewhere,它描述了如何做到这一点(一直向下滚动到 cmets)。

评论者的技术允许识别 WiFi 和蓝牙接口,其中所有其他类型可以组合在一起。如果目标只是将 WiFi 与以太网适配器分开,那应该就足够了。

查询是(Powershell 示例):

$nics = Get-WmiObject -Namespace "root/CIMV2" -Query "SELECT * FROM Win32_NetworkAdapter"
$types = Get-WmiObject -Namespace "root/WMI" -Query "SELECT * FROM MSNdis_PhysicalMediumType"

第一个查询是提供适配器列表的常用方法。如前所述,可以通过许多其他选择标准将其过滤为仅包含有效的物理设备。

第二个查询返回一个带有 NdisPhysicalMediumType 属性的 WMI 对象,根据链接的站点,其值为 9 表示 WiFi,10 表示蓝牙,并且0 用于以太网和大多数其他适配器类型。

似乎必须使用第一个查询的NameDescription 属性和第二个查询的InstanceName 属性在脚本中手动完成这两个查询。

【讨论】:

【参考方案3】:
select * from Win32_NetworkAdapter where NetConnectionID LIKE "%Wireless%" or NetConnectionID LIKE "%Wi-Fi%"

【讨论】:

字符串搜索根本不够可靠。

以上是关于通过 WMI 确定网络适配器类型的主要内容,如果未能解决你的问题,请参考以下文章

在 .NET 中以编程方式配置网络适配器的最佳方式

电脑出现WMI效能适配器是怎么回事

如何检索系统上网络适配器的 GUID?

WMI调用方法

虚拟机无法连接到主机上的网络咋办?

如何确定我的计算机正在使用哪个网络适配器?