TL;DR version of this question: WMI Win32_NetworkAdapter class contains information I need, but is too slow. What\'s a faster method of getting information for the MACAddre
You should be able to get everything you need from the System.Net
namespace. For example, the following sample is lifted from MSDN and does what you asked for in the original version of the question. It displays the physical addresses of all interfaces on the local computer.
public static void ShowNetworkInterfaces()
{
IPGlobalProperties computerProperties = IPGlobalProperties.GetIPGlobalProperties();
NetworkInterface[] nics = NetworkInterface.GetAllNetworkInterfaces();
Console.WriteLine("Interface information for {0}.{1} ",
computerProperties.HostName, computerProperties.DomainName);
if (nics == null || nics.Length < 1)
{
Console.WriteLine(" No network interfaces found.");
return;
}
Console.WriteLine(" Number of interfaces .................... : {0}", nics.Length);
foreach (NetworkInterface adapter in nics)
{
IPInterfaceProperties properties = adapter.GetIPProperties(); // .GetIPInterfaceProperties();
Console.WriteLine();
Console.WriteLine(adapter.Description);
Console.WriteLine(String.Empty.PadLeft(adapter.Description.Length,'='));
Console.WriteLine(" Interface type .......................... : {0}", adapter.NetworkInterfaceType);
Console.Write(" Physical address ........................ : ");
PhysicalAddress address = adapter.GetPhysicalAddress();
byte[] bytes = address.GetAddressBytes();
for(int i = 0; i< bytes.Length; i++)
{
// Display the physical address in hexadecimal.
Console.Write("{0}", bytes[i].ToString("X2"));
// Insert a hyphen after each byte, unless we are at the end of the
// address.
if (i != bytes.Length -1)
{
Console.Write("-");
}
}
Console.WriteLine();
}
}
I wound up cutting WMI completely out of the equation and made a significant improvement while still getting the information I wanted. As noted with WMI, it was taking > 0.30 seconds to get results. With my version, I can get the same information in about 0.01 seconds.
I used the setup API, configuration manager API, and then made OID requests directly on the NDIS network driver to get the MAC address. The setup API seems obnoxiously slow, especially when getting things like property values. It's imperative to keep setup API calls at a minimum. (You can actually see just how bad it is by looking at how long it takes to load the "Details" tab of a device in Device manager).
A guess on why WMI was so slow: I noted that WMI's Win32_NetworkAdapter always took the same amount of time no matter which subset of properties I queried. Seems like the WMI Win32_NetworkAdapter class programmers were lazy and didn't optimize their class to only gather requested information like other WMI classes do. They probably gather all information, whether requested or not. They probably significantly rely on Setup API to do this, and the excessive calls to the slow Setup API to get unwanted information is what makes it so slow.
High level overview of what I did:
The result is a robust indication of MAC addresses on the PC that should be immune to "fake" network cards made by VMware, VirtualBox, largely immune to network cards that are temporarily disabled, and immune to transient network cards attached via USB, ExpressCard, PC Card, or any future removable interface.
EDIT: IOCTL_NDIS_QUERY_GLOBAL_STATS isn't supported by all network cards. The vast majority work, but some Intel cards do not. See How to reliably and quickly get the MAC address of a network card given its device instance ID