本文示範兩種層級的網路設定修改:
⚠️ 警告:修改登錄表需管理員權限,錯誤可能導致網路失效,請先備份登錄表並具備恢復能力。
using Microsoft.Win32; // 登錄表操作
using System.Management; // WMI 查詢與設定 (需參考 System.Management.dll)
using System.Net.NetworkInformation; // 取得網卡資訊
using System.ServiceProcess; // 重啟網路服務 (可選)
public class NetworkAdapterInfo {
public string Name { get; set; } // 如 "本地連接"
public string Description { get; set; } // 如 "Realtek PCIe GBE Family Controller"
public string MacAddress { get; set; } // 物理 MAC
public string AdapterId { get; set; } // GUID,對應登錄表子鍵名
public string IpAddress { get; set; }
public string SubnetMask { get; set; }
}
public static List GetAdapters() {
var list = new List();
foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces()) {
if (nic.OperationalStatus != OperationalStatus.Up) continue; // 可選:只抓啟用的
var ipProps = nic.GetIPProperties();
string ip = "", mask = "";
foreach (var ua in ipProps.UnicastAddresses) {
if (ua.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork) {
ip = ua.Address.ToString();
mask = ua.IPv4Mask.ToString();
break;
}
}
list.Add(new NetworkAdapterInfo {
Name = nic.Name,
Description = nic.Description,
MacAddress = nic.GetPhysicalAddress().ToString(),
AdapterId = nic.Id, // 格式: {GUID}
IpAddress = ip,
SubnetMask = mask
});
}
return list;
}
// 登錄表路徑: HKLM\SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}\{0000,0001...}
private const string NetClassKeyPath = @"SYSTEM\CurrentControlSet\Control\Class\{4D36E972-E325-11CE-BFC1-08002BE10318}";
public static bool SetMacAddress(string adapterId, string newMac) {
// newMac 格式: 12 碼十六進位,不含分隔符,如 "001122334455"
if (!Regex.IsMatch(newMac, @"^[0-9A-Fa-f]{12}$")) throw new ArgumentException("MAC 格式錯誤");
using (RegistryKey classKey = Registry.LocalMachine.OpenSubKey(NetClassKeyPath, true)) {
if (classKey == null) return false;
foreach (string subKeyName in classKey.GetSubKeyNames()) {
using (RegistryKey adapterKey = classKey.OpenSubKey(subKeyName, true)) {
if (adapterKey == null) continue;
// 比對 NetCfgInstanceId 確認是目標網卡
object val = adapterKey.GetValue("NetCfgInstanceId");
if (val != null && val.ToString().Equals(adapterId, StringComparison.OrdinalIgnoreCase)) {
// 寫入 NetworkAddress (註冊表值型別為 String)
adapterKey.SetValue("NetworkAddress", newMac);
// 部分驅動程式需同時寫入 Ndi\params\NetworkAddress
using (RegistryKey ndiParams = adapterKey.OpenSubKey(@"Ndi\params\NetworkAddress", true)) {
if (ndiParams != null) {
ndiParams.SetValue("Default", newMac);
ndiParams.SetValue("ParamDesc", "Network Address");
}
}
return true;
}
}
}
}
return false;
}
// 登錄表 IP 路徑: HKLM\SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{GUID}
public static bool SetStaticIpRegistry(string adapterId, string ip, string subnet) {
string tcpipPath = $@"SYSTEM\CurrentControlSet\Services\Tcpip\Parameters\Interfaces\{adapterId}";
using (RegistryKey key = Registry.LocalMachine.OpenSubKey(tcpipPath, true)) {
if (key == null) return false;
key.SetValue("IPAddress", new string[] { ip }, RegistryValueKind.MultiString);
key.SetValue("SubnetMask", new string[] { subnet }, RegistryValueKind.MultiString);
// 可選: DefaultGateway, NameServer (DNS)
return true;
}
}
// WMI 即時套用 (不需重啟)
public static bool ApplyStaticIpWmi(string adapterId, string ip, string subnet, string gateway = null, string dns = null) {
try {
ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc) {
if (!(bool)mo["IPEnabled"]) continue;
if (mo["SettingID"].ToString().Equals(adapterId, StringComparison.OrdinalIgnoreCase)) {
ManagementBaseObject inParams = mo.GetMethodParameters("EnableStatic");
inParams["IPAddress"] = new string[] { ip };
inParams["SubnetMask"] = new string[] { subnet };
ManagementBaseObject outParams = mo.InvokeMethod("EnableStatic", inParams, null);
uint ret = (uint)outParams["ReturnValue"];
if (ret != 0) return false; // 0=成功
if (!string.IsNullOrEmpty(gateway)) {
inParams = mo.GetMethodParameters("SetGateways");
inParams["DefaultIPGateway"] = new string[] { gateway };
inParams["GatewayCostMetric"] = new int[] { 1 };
mo.InvokeMethod("SetGateways", inParams, null);
}
if (!string.IsNullOrEmpty(dns)) {
inParams = mo.GetMethodParameters("SetDNSServerSearchOrder");
inParams["DNSServerSearchOrder"] = new string[] { dns };
mo.InvokeMethod("SetDNSServerSearchOrder", inParams, null);
}
return true;
}
}
} catch (Exception ex) {
// 記錄日誌
}
return false;
}
public static void RestartAdapter(string adapterName) {
// 方法 1: WMI Disable/Enable
ManagementClass mc = new ManagementClass("Win32_NetworkAdapter");
foreach (ManagementObject mo in mc.GetInstances()) {
if (mo["NetConnectionID"].ToString() == adapterName) {
mo.InvokeMethod("Disable", null);
System.Threading.Thread.Sleep(2000);
mo.InvokeMethod("Enable", null);
break;
}
}
// 方法 2: 重啟網路服務 (影響所有網卡)
// using (ServiceController sc = new ServiceController("Tcpip")) { sc.Stop(); sc.Start(); }
}
GetAdapters() 填入下拉選單SetMacAddress → SetStaticIpRegistry → ApplyStaticIpWmi → RestartAdapterGetAdapters() 比對| 問題 | 說明 |
|---|---|
| MAC 修改後不生效 | 部分網卡驅動不支援 NetworkAddress 覆寫;需確認驅動版本或至裝置管理員手動設定 |
| 登錄表 IP 修改需重啟 | 登錄表僅為持久化設定,WMI EnableStatic 才能即時生效;建議兩者皆執行 |
| 權限不足 | 需以管理員身分執行 (app.manifest 加入 requireAdministrator) |
| WMI 查詢慢 | 首次查詢較慢,可快取 ManagementObjectSearcher 結果 |