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;
// 設備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
);
}
}