using System;
using System.Collections.Generic;
using System.Management;
using System.Runtime.InteropServices;
using System.Text.RegularExpressions;
namespace Splash.Util
{
public class NetworkAdapterInformation
{
public String PNPDeviceID; // 设备ID
public UInt32 Index; // 在系统注册表中的索引号
public String ProductName; // 产品名称
public String ServiceName; // 服务名称
public String MACAddress; // 网卡当前物理地址
public String PermanentAddress; // 网卡原生物理地址
public String IPv4Address; // IP 地址
public String IPv4Subnet; // 子网掩码
public String IPv4Gateway; // 默认网关
public Boolean IPEnabled; // 有效状态
}
/// <summary>
/// 基于WMI获取本机真实网卡信息
/// </summary>
public static class NetworkAdapter
{
/// <summary>
/// 获取本机真实网卡信息,包括物理地址和IP地址
/// </summary>
/// <param name="isIncludeUsb">是否包含USB网卡,默认为不包含</param>
/// <returns>本机真实网卡信息</returns>
public static NetworkAdapterInformation[] GetNetworkAdapterInformation(Boolean isIncludeUsb = false)
{ // IPv4正则表达式
const String IPv4RegularExpression = "^(?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))$";
// 注意:只获取已连接的网卡
String NetworkAdapterQueryString;
if (isIncludeUsb)
NetworkAdapterQueryString = "SELECT * FROM Win32_NetworkAdapter WHERE (NetConnectionStatus = 2) AND (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))";
else
NetworkAdapterQueryString = "SELECT * FROM Win32_NetworkAdapter WHERE (NetConnectionStatus = 2) AND (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%')) AND (NOT (PNPDeviceID LIKE 'USB%'))";
ManagementObjectCollection NetworkAdapterQueryCollection = new ManagementObjectSearcher(NetworkAdapterQueryString).Get();
if (NetworkAdapterQueryCollection == null) return null;
List<NetworkAdapterInformation> NetworkAdapterInformationCollection = new List<NetworkAdapterInformation>(NetworkAdapterQueryCollection.Count);
foreach (ManagementObject mo in NetworkAdapterQueryCollection)
{
NetworkAdapterInformation NetworkAdapterItem = new NetworkAdapterInformation();
NetworkAdapterItem.PNPDeviceID = mo["PNPDeviceID"] as String;
NetworkAdapterItem.Index = (UInt32)mo["Index"];
NetworkAdapterItem.ProductName = mo["ProductName"] as String;
NetworkAdapterItem.ServiceName = mo["ServiceName"] as String;
NetworkAdapterItem.MACAddress = mo["MACAddress"] as String; // 网卡当前物理地址
// 网卡原生物理地址
NetworkAdapterItem.PermanentAddress = GetNetworkAdapterPermanentAddress(NetworkAdapterItem.PNPDeviceID);
// 获取网卡配置信息
String ConfigurationQueryString = "SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = " + NetworkAdapterItem.Index.ToString();
ManagementObjectCollection ConfigurationQueryCollection = new ManagementObjectSearcher(ConfigurationQueryString).Get();
if (ConfigurationQueryCollection == null) continue;
foreach (ManagementObject nacmo in ConfigurationQueryCollection)
{
String[] IPCollection = nacmo["IPAddress"] as String[]; // IP地址
if (IPCollection != null)
{
foreach (String adress in IPCollection)
{
Match match = Regex.Match(adress, IPv4RegularExpression);
if (match.Success) { NetworkAdapterItem.IPv4Address = adress; break; }
}
}
IPCollection = nacmo["IPSubnet"] as String[]; // 子网掩码
if (IPCollection != null)
{
foreach (String address in IPCollection)
{
Match match = Regex.Match(address, IPv4RegularExpression);
if (match.Success) { NetworkAdapterItem.IPv4Subnet = address; break; }
}
}
IPCollection = nacmo["DefaultIPGateway"] as String[]; // 默认网关
if (IPCollection != null)
{
foreach (String address in IPCollection)
{
Match match = Regex.Match(address, IPv4RegularExpression);
if (match.Success) { NetworkAdapterItem.IPv4Gateway = address; break; }
}
}
NetworkAdapterItem.IPEnabled = (Boolean)nacmo["IPEnabled"];
}
NetworkAdapterInformationCollection.Add(NetworkAdapterItem);
}
if (NetworkAdapterInformationCollection.Count > 0) return NetworkAdapterInformationCollection.ToArray(); else return null;
}
/// <summary>
/// 获取网卡原生物理地址
/// </summary>
/// <param name="PNPDeviceID">设备ID</param>
/// <returns>网卡原生物理地址</returns>
public static String GetNetworkAdapterPermanentAddress(String PNPDeviceID)
{
const UInt32 FILE_SHARE_READ = 0x00000001;
const UInt32 FILE_SHARE_WRITE = 0x00000002;
const UInt32 OPEN_EXISTING = 3;
const UInt32 OID_802_3_PERMANENT_ADDRESS = 0x01010101;
const UInt32 IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x00170002;
IntPtr INVALID_HANDLE_VALUE = new IntPtr(-1);
// 生成设备路径名
String DevicePath = "\\.\" + PNPDeviceID.Replace('\', '#') + "#{ad498944-762f-11d0-8dcb-00c04fc3358c}";
// 获取设备句柄
IntPtr hDeviceFile = CreateFile(DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if (hDeviceFile != INVALID_HANDLE_VALUE)
{
Byte[] ucData = new Byte[8];
Int32 nBytesReturned;
// 获取原生MAC地址
UInt32 dwOID = OID_802_3_PERMANENT_ADDRESS;
Boolean isOK = DeviceIoControl(hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS, ref dwOID, Marshal.SizeOf(dwOID), ucData, ucData.Length, out nBytesReturned, IntPtr.Zero);
CloseHandle(hDeviceFile);
if (isOK)
{
System.Text.StringBuilder sb = new System.Text.StringBuilder(nBytesReturned * 3);
foreach (Byte b in ucData)
{
sb.Append(b.ToString("X2"));
sb.Append(':');
}
return sb.ToString(0, nBytesReturned * 3 - 1);
}
}
return null;
}
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
public static extern IntPtr CreateFile(
String lpFileName,
UInt32 dwDesiredAccess,
UInt32 dwShareMode,
IntPtr lpSecurityAttributes,
UInt32 dwCreationDisposition,
UInt32 dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern Boolean CloseHandle(IntPtr hObject);
[DllImport("kernel32.dll", CharSet = CharSet.Ansi, SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
internal static extern Boolean DeviceIoControl(
IntPtr hDevice,
UInt32 dwIoControlCode,
ref UInt32 lpInBuffer,
Int32 nInBufferSize,
Byte[] lpOutBuffer,
Int32 nOutBufferSize,
out Int32 nBytesReturned,
IntPtr lpOverlapped
);
}
}
using
System;
using
System.Collections.Generic;
using
System.Management;
using
System.Runtime.InteropServices;
using
System.Text.RegularExpressions;
namespace
Splash.Util
{
public
class
NetworkAdapterInformation
{
public
String PNPDeviceID;
public
UInt32 Index;
public
String ProductName;
public
String ServiceName;
public
String MACAddress;
public
String PermanentAddress;
public
String IPv4Address;
public
String IPv4Subnet;
public
String IPv4Gateway;
public
Boolean IPEnabled;
}
/// <summary>
/// 基于WMI获取本机真实网卡信息
/// </summary>
public
static
class
NetworkAdapter
{
/// <summary>
/// 获取本机真实网卡信息,包括物理地址和IP地址
/// </summary>
/// <param name="isIncludeUsb">是否包含USB网卡,默认为不包含</param>
/// <returns>本机真实网卡信息</returns>
public
static
NetworkAdapterInformation[] GetNetworkAdapterInformation(Boolean isIncludeUsb =
false
)
{
const
String IPv4RegularExpression =
"^(?:(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))\.){3}(?:25[0-5]|2[0-4]\d|((1\d{2})|([1-9]?\d)))$"
;
String NetworkAdapterQueryString;
if
(isIncludeUsb)
NetworkAdapterQueryString =
"SELECT * FROM Win32_NetworkAdapter WHERE (NetConnectionStatus = 2) AND (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%'))"
;
else
NetworkAdapterQueryString =
"SELECT * FROM Win32_NetworkAdapter WHERE (NetConnectionStatus = 2) AND (MACAddress IS NOT NULL) AND (NOT (PNPDeviceID LIKE 'ROOT%')) AND (NOT (PNPDeviceID LIKE 'USB%'))"
;
ManagementObjectCollection NetworkAdapterQueryCollection =
new
ManagementObjectSearcher(NetworkAdapterQueryString).Get();
if
(NetworkAdapterQueryCollection ==
null
)
return
null
;
List<NetworkAdapterInformation> NetworkAdapterInformationCollection =
new
List<NetworkAdapterInformation>(NetworkAdapterQueryCollection.Count);
foreach
(ManagementObject mo
in
NetworkAdapterQueryCollection)
{
NetworkAdapterInformation NetworkAdapterItem =
new
NetworkAdapterInformation();
NetworkAdapterItem.PNPDeviceID = mo[
"PNPDeviceID"
]
as
String;
NetworkAdapterItem.Index = (UInt32)mo[
"Index"
];
NetworkAdapterItem.ProductName = mo[
"ProductName"
]
as
String;
NetworkAdapterItem.ServiceName = mo[
"ServiceName"
]
as
String;
NetworkAdapterItem.MACAddress = mo[
"MACAddress"
]
as
String;
NetworkAdapterItem.PermanentAddress = GetNetworkAdapterPermanentAddress(NetworkAdapterItem.PNPDeviceID);
String ConfigurationQueryString =
"SELECT * FROM Win32_NetworkAdapterConfiguration WHERE Index = "
+ NetworkAdapterItem.Index.ToString();
ManagementObjectCollection ConfigurationQueryCollection =
new
ManagementObjectSearcher(ConfigurationQueryString).Get();
if
(ConfigurationQueryCollection ==
null
)
continue
;
foreach
(ManagementObject nacmo
in
ConfigurationQueryCollection)
{
String[] IPCollection = nacmo[
"IPAddress"
]
as
String[];
if
(IPCollection !=
null
)
{
foreach
(String adress
in
IPCollection)
{
Match match = Regex.Match(adress, IPv4RegularExpression);
if
(match.Success) { NetworkAdapterItem.IPv4Address = adress;
break
; }
}
}
IPCollection = nacmo[
"IPSubnet"
]
as
String[];
if
(IPCollection !=
null
)
{
foreach
(String address
in
IPCollection)
{
Match match = Regex.Match(address, IPv4RegularExpression);
if
(match.Success) { NetworkAdapterItem.IPv4Subnet = address;
break
; }
}
}
IPCollection = nacmo[
"DefaultIPGateway"
]
as
String[];
if
(IPCollection !=
null
)
{
foreach
(String address
in
IPCollection)
{
Match match = Regex.Match(address, IPv4RegularExpression);
if
(match.Success) { NetworkAdapterItem.IPv4Gateway = address;
break
; }
}
}
NetworkAdapterItem.IPEnabled = (Boolean)nacmo[
"IPEnabled"
];
}
NetworkAdapterInformationCollection.Add(NetworkAdapterItem);
}
if
(NetworkAdapterInformationCollection.Count > 0)
return
NetworkAdapterInformationCollection.ToArray();
else
return
null
;
}
/// <summary>
/// 获取网卡原生物理地址
/// </summary>
/// <param name="PNPDeviceID">设备ID</param>
/// <returns>网卡原生物理地址</returns>
public
static
String GetNetworkAdapterPermanentAddress(String PNPDeviceID)
{
const
UInt32 FILE_SHARE_READ = 0x00000001;
const
UInt32 FILE_SHARE_WRITE = 0x00000002;
const
UInt32 OPEN_EXISTING = 3;
const
UInt32 OID_802_3_PERMANENT_ADDRESS = 0x01010101;
const
UInt32 IOCTL_NDIS_QUERY_GLOBAL_STATS = 0x00170002;
IntPtr INVALID_HANDLE_VALUE =
new
IntPtr(-1);
String DevicePath =
"\\.\"
+ PNPDeviceID.Replace(
'\'
,
'#'
) +
"#{ad498944-762f-11d0-8dcb-00c04fc3358c}"
;
IntPtr hDeviceFile = CreateFile(DevicePath, 0, FILE_SHARE_READ | FILE_SHARE_WRITE, IntPtr.Zero, OPEN_EXISTING, 0, IntPtr.Zero);
if
(hDeviceFile != INVALID_HANDLE_VALUE)
{
Byte[] ucData =
new
Byte[8];
Int32 nBytesReturned;
UInt32 dwOID = OID_802_3_PERMANENT_ADDRESS;
Boolean isOK = DeviceIoControl(hDeviceFile, IOCTL_NDIS_QUERY_GLOBAL_STATS,
ref
dwOID, Marshal.SizeOf(dwOID), ucData, ucData.Length,
out
nBytesReturned, IntPtr.Zero);
CloseHandle(hDeviceFile);
if
(isOK)
{
System.Text.StringBuilder sb =
new
System.Text.StringBuilder(nBytesReturned * 3);
foreach
(Byte b
in
ucData)
{
sb.Append(b.ToString(
"X2"
));
sb.Append(
':'
);
}
return
sb.ToString(0, nBytesReturned * 3 - 1);
}
}
return
null
;
}
[DllImport(
"kernel32.dll"
, CharSet = CharSet.Auto, SetLastError =
true
)]
public
static
extern
IntPtr CreateFile(
String lpFileName,
UInt32 dwDesiredAccess,
UInt32 dwShareMode,
IntPtr lpSecurityAttributes,
UInt32 dwCreationDisposition,
UInt32 dwFlagsAndAttributes,
IntPtr hTemplateFile
);
[DllImport(
"kernel32.dll"
, SetLastError =
true
)]
[
return
: MarshalAs(UnmanagedType.Bool)]
public
static
extern
Boolean CloseHandle(IntPtr hObject);
[DllImport(
"kernel32.dll"
, CharSet = CharSet.Ansi, SetLastError =
true
)]
[
return
: MarshalAs(UnmanagedType.Bool)]
internal
static
extern
Boolean DeviceIoControl(
IntPtr hDevice,
UInt32 dwIoControlCode,
ref
UInt32 lpInBuffer,
Int32 nInBufferSize,
Byte[] lpOutBuffer,
Int32 nOutBufferSize,
out
Int32 nBytesReturned,
IntPtr lpOverlapped
);
}
}