How can you change Network settings (IP Address, DNS, WINS, Host Name) with code in C#
我正在为要用作其他机器备份的机器开发向导。当它替换现有机器时,它需要设置其 IP 地址、DNS、WINS 和主机名以匹配被替换的机器。
.net (C#) 中是否有允许我以编程方式执行此操作的库?
有多个网卡,每个都需要单独设置。
编辑
感谢 TimothyP 提供的示例。它让我在正确的Rails上前进,快速的回复很棒。
谢谢巴列山德。你的代码很完美。我很着急,已经修改了 TimothyP 链接到的示例,但我很想早点得到你的代码。
我还开发了一个使用类似技术更改计算机名称的例程。我会在以后发布它,所以如果您想了解更新,请订阅这个问题的 RSS 提要。我可能会在今天晚些时候或周一稍作清理后把它弄起来。
几分钟就搞定了:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 | using System; using System.Management; namespace WindowsFormsApplication_CS { class NetworkManagement { public void setIP(string ip_address, string subnet_mask) { ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection objMOC = objMC.GetInstances(); foreach (ManagementObject objMO in objMOC) { if ((bool)objMO["IPEnabled"]) { ManagementBaseObject setIP; ManagementBaseObject newIP = objMO.GetMethodParameters("EnableStatic"); newIP["IPAddress"] = new string[] { ip_address }; newIP["SubnetMask"] = new string[] { subnet_mask }; setIP = objMO.InvokeMethod("EnableStatic", newIP, null); } } } public void setGateway(string gateway) { ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection objMOC = objMC.GetInstances(); foreach (ManagementObject objMO in objMOC) { if ((bool)objMO["IPEnabled"]) { ManagementBaseObject setGateway; ManagementBaseObject newGateway = objMO.GetMethodParameters("SetGateways"); newGateway["DefaultIPGateway"] = new string[] { gateway }; newGateway["GatewayCostMetric"] = new int[] { 1 }; setGateway = objMO.InvokeMethod("SetGateways", newGateway, null); } } } public void setDNS(string NIC, string DNS) { ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection objMOC = objMC.GetInstances(); foreach (ManagementObject objMO in objMOC) { if ((bool)objMO["IPEnabled"]) { // if you are using the System.Net.NetworkInformation.NetworkInterface // you'll need to change this line to // if (objMO["Caption"].ToString().Contains(NIC)) // and pass in the Description property instead of the name if (objMO["Caption"].Equals(NIC)) { ManagementBaseObject newDNS = objMO.GetMethodParameters("SetDNSServerSearchOrder"); newDNS["DNSServerSearchOrder"] = DNS.Split(','); ManagementBaseObject setDNS = objMO.InvokeMethod("SetDNSServerSearchOrder", newDNS, null); } } } } public void setWINS(string NIC, string priWINS, string secWINS) { ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection objMOC = objMC.GetInstances(); foreach (ManagementObject objMO in objMOC) { if ((bool)objMO["IPEnabled"]) { if (objMO["Caption"].Equals(NIC)) { ManagementBaseObject setWINS; ManagementBaseObject wins = objMO.GetMethodParameters("SetWINSServer"); wins.SetPropertyValue("WINSPrimaryServer", priWINS); wins.SetPropertyValue("WINSSecondaryServer", secWINS); setWINS = objMO.InvokeMethod("SetWINSServer", wins, null); } } } } } } |
稍微重构了 balexandre 的代码,以便处理对象并使用 C# 3.5 的新语言特性(Linq、var 等)。还将变量重命名为更有意义的名称。我还合并了一些功能,以便能够以更少的 WMI 交互进行更多配置。我删除了 WINS 代码,因为我不再需要配置 WINS。如果需要,请随意添加 WINS 代码。
对于任何人都喜欢使用重构/现代化代码的情况,我将其放回社区。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 | /// <summary> /// Helper class to set networking configuration like IP address, DNS servers, etc. /// </summary> public class NetworkConfigurator { /// <summary> /// Set's a new IP Address and it's Submask of the local machine /// </summary> /// <param name="ipAddress">The IP Address</param> /// <param name="subnetMask">The Submask IP Address</param> /// <param name="gateway">The gateway.</param> /// <remarks>Requires a reference to the System.Management namespace</remarks> public void SetIP(string ipAddress, string subnetMask, string gateway) { using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (var networkConfigs = networkConfigMng.GetInstances()) { foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(managementObject => (bool)managementObject["IPEnabled"])) { using (var newIP = managementObject.GetMethodParameters("EnableStatic")) { // Set new IP address and subnet if needed if ((!String.IsNullOrEmpty(ipAddress)) || (!String.IsNullOrEmpty(subnetMask))) { if (!String.IsNullOrEmpty(ipAddress)) { newIP["IPAddress"] = new[] { ipAddress }; } if (!String.IsNullOrEmpty(subnetMask)) { newIP["SubnetMask"] = new[] { subnetMask }; } managementObject.InvokeMethod("EnableStatic", newIP, null); } // Set mew gateway if needed if (!String.IsNullOrEmpty(gateway)) { using (var newGateway = managementObject.GetMethodParameters("SetGateways")) { newGateway["DefaultIPGateway"] = new[] { gateway }; newGateway["GatewayCostMetric"] = new[] { 1 }; managementObject.InvokeMethod("SetGateways", newGateway, null); } } } } } } } /// <summary> /// Set's the DNS Server of the local machine /// </summary> /// <param name="nic">NIC address</param> /// <param name="dnsServers">Comma seperated list of DNS server addresses</param> /// <remarks>Requires a reference to the System.Management namespace</remarks> public void SetNameservers(string nic, string dnsServers) { using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (var networkConfigs = networkConfigMng.GetInstances()) { foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(objMO => (bool)objMO["IPEnabled"] && objMO["Caption"].Equals(nic))) { using (var newDNS = managementObject.GetMethodParameters("SetDNSServerSearchOrder")) { newDNS["DNSServerSearchOrder"] = dnsServers.Split(','); managementObject.InvokeMethod("SetDNSServerSearchOrder", newDNS, null); } } } } } } |
我喜欢 WMILinq 解决方案。虽然不能完全解决您的问题,但请在下面找到它的味道:
1 2 3 4 5 6 7 8 9 10 11 12 | using (WmiContext context = new WmiContext(@"\\\\.")) { context.ManagementScope.Options.Impersonation = ImpersonationLevel.Impersonate; context.Log = Console.Out; var dnss = from nic in context.Source<Win32_NetworkAdapterConfiguration>() where nic.IPEnabled select nic; var ips = from s in dnss.SelectMany(dns => dns.DNSServerSearchOrder) select IPAddress.Parse(s); } |
http://www.codeplex.com/linq2wmi
更明确的解决方案是使用命令
1 | netsh interface ip set address"Local Area Connection" static 192.168.0.10 255.255.255.0 |
其中"本地连接"是网络适配器的名称。您可以在 windows 网络连接中找到它,有时它只是简单地命名为 "Ethernet"。
这里有两种方法来设置 IP 以及将 IP 设置回 DHCP "自动获取 IP 地址"
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 | public bool SetIP(string networkInterfaceName, string ipAddress, string subnetMask, string gateway = null) { var networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(nw => nw.Name == networkInterfaceName); var ipProperties = networkInterface.GetIPProperties(); var ipInfo = ipProperties.UnicastAddresses.FirstOrDefault(ip => ip.Address.AddressFamily == AddressFamily.InterNetwork); var currentIPaddress = ipInfo.Address.ToString(); var currentSubnetMask = ipInfo.IPv4Mask.ToString(); var isDHCPenabled = ipProperties.GetIPv4Properties().IsDhcpEnabled; if (!isDHCPenabled && currentIPaddress == ipAddress && currentSubnetMask == subnetMask) return true; // no change necessary var process = new Process { StartInfo = new ProcessStartInfo("netsh", $"interface ip set address "{networkInterfaceName}" static {ipAddress} {subnetMask}" + (string.IsNullOrWhiteSpace(gateway) ?"" : $"{gateway} 1")) { Verb ="runas" } }; process.Start(); var successful = process.ExitCode == 0; process.Dispose(); return successful; } public bool SetDHCP(string networkInterfaceName) { var networkInterface = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(nw => nw.Name == networkInterfaceName); var ipProperties = networkInterface.GetIPProperties(); var isDHCPenabled = ipProperties.GetIPv4Properties().IsDhcpEnabled; if (isDHCPenabled) return true; // no change necessary var process = new Process { StartInfo = new ProcessStartInfo("netsh", $"interface ip set address "{networkInterfaceName}" dhcp") { Verb ="runas" } }; process.Start(); var successful = process.ExitCode == 0; process.Dispose(); return successful; } |
建立在此处其他答案之上的更简洁的示例。我利用 Visual Studio 附带的代码生成来删除大部分额外的调用代码,并将其替换为类型化对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 | using System; using System.Management; namespace Utils { class NetworkManagement { /// <summary> /// Returns a list of all the network interface class names that are currently enabled in the system /// </summary> /// <returns>list of nic names</returns> public static string[] GetAllNicDescriptions() { List<string> nics = new List<string>(); using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (var networkConfigs = networkConfigMng.GetInstances()) { foreach (var config in networkConfigs.Cast<ManagementObject>() .Where(mo => (bool)mo["IPEnabled"]) .Select(x=> new NetworkAdapterConfiguration(x))) { nics.Add(config.Description); } } } return nics.ToArray(); } /// <summary> /// Set's the DNS Server of the local machine /// </summary> /// <param name="nicDescription">The full description of the network interface class</param> /// <param name="dnsServers">Comma seperated list of DNS server addresses</param> /// <remarks>Requires a reference to the System.Management namespace</remarks> public static bool SetNameservers(string nicDescription, string[] dnsServers, bool restart = false) { using (ManagementClass networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (ManagementObjectCollection networkConfigs = networkConfigMng.GetInstances()) { foreach (ManagementObject mboDNS in networkConfigs.Cast<ManagementObject>().Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription)) { // NAC class was generated by opening a developer console and entering: // mgmtclassgen Win32_NetworkAdapterConfiguration -p NetworkAdapterConfiguration.cs // See: http://blog.opennetcf.com/2008/06/24/disableenable-network-connections-under-vista/ using (NetworkAdapterConfiguration config = new NetworkAdapterConfiguration(mboDNS)) { if (config.SetDNSServerSearchOrder(dnsServers) == 0) { RestartNetworkAdapter(nicDescription); } } } } } return false; } /// <summary> /// Restarts a given Network adapter /// </summary> /// <param name="nicDescription">The full description of the network interface class</param> public static void RestartNetworkAdapter(string nicDescription) { using (ManagementClass networkConfigMng = new ManagementClass("Win32_NetworkAdapter")) { using (ManagementObjectCollection networkConfigs = networkConfigMng.GetInstances()) { foreach (ManagementObject mboDNS in networkConfigs.Cast<ManagementObject>().Where(mo=> (string)mo["Description"] == nicDescription)) { // NA class was generated by opening dev console and entering // mgmtclassgen Win32_NetworkAdapter -p NetworkAdapter.cs using (NetworkAdapter adapter = new NetworkAdapter(mboDNS)) { adapter.Disable(); adapter.Enable(); Thread.Sleep(4000); // Wait a few secs until exiting, this will give the NIC enough time to re-connect return; } } } } } /// <summary> /// Get's the DNS Server of the local machine /// </summary> /// <param name="nicDescription">The full description of the network interface class</param> public static string[] GetNameservers(string nicDescription) { using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (var networkConfigs = networkConfigMng.GetInstances()) { foreach (var config in networkConfigs.Cast<ManagementObject>() .Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription) .Select( x => new NetworkAdapterConfiguration(x))) { return config.DNSServerSearchOrder; } } } return null; } /// <summary> /// Set's a new IP Address and it's Submask of the local machine /// </summary> /// <param name="nicDescription">The full description of the network interface class</param> /// <param name="ipAddresses">The IP Address</param> /// <param name="subnetMask">The Submask IP Address</param> /// <param name="gateway">The gateway.</param> /// <remarks>Requires a reference to the System.Management namespace</remarks> public static void SetIP(string nicDescription, string[] ipAddresses, string subnetMask, string gateway) { using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (var networkConfigs = networkConfigMng.GetInstances()) { foreach (var config in networkConfigs.Cast<ManagementObject>() .Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription) .Select( x=> new NetworkAdapterConfiguration(x))) { // Set the new IP and subnet masks if needed config.EnableStatic(ipAddresses, Array.ConvertAll(ipAddresses, _ => subnetMask)); // Set mew gateway if needed if (!String.IsNullOrEmpty(gateway)) { config.SetGateways(new[] {gateway}, new ushort[] {1}); } } } } } } } |
完整来源:
https://github.com/sverrirs/DnsHelper/blob/master/src/DnsHelperUI/NetworkManagement.cs
这可能更清楚:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | static NetworkInterface GetNetworkInterface(string macAddress) { foreach(NetworkInterface ni in NetworkInterface.GetAllNetworkInterfaces()) { if (macAddress == ni.GetPhysicalAddress().ToString()) return ni; } return null; } static ManagementObject GetNetworkInterfaceManagementObject(string macAddress) { NetworkInterface ni = GetNetworkInterface(macAddress); if (ni == null) return null; ManagementClass managementClass = new ManagementClass("Win32_NetworkAdapterConfiguration"); ManagementObjectCollection moc = managementClass.GetInstances(); foreach(ManagementObject mo in moc) { if (mo["settingID"].ToString() == ni.Id) return mo; } return null; } static bool SetupNIC(string macAddress, string ip, string subnet, string gateway, string dns) { try { ManagementObject mo = GetNetworkInterfaceManagementObject(macAddress); //Set IP ManagementBaseObject mboIP = mo.GetMethodParameters("EnableStatic"); mboIP["IPAddress"] = new string[] { ip }; mboIP["SubnetMask"] = new string[] { subnet }; mo.InvokeMethod("EnableStatic", mboIP, null); //Set Gateway ManagementBaseObject mboGateway = mo.GetMethodParameters("SetGateways"); mboGateway["DefaultIPGateway"] = new string[] { gateway }; mboGateway["GatewayCostMetric"] = new int[] { 1 }; mo.InvokeMethod("SetGateways", mboGateway, null); //Set DNS ManagementBaseObject mboDNS = mo.GetMethodParameters("SetDNSServerSearchOrder"); mboDNS["DNSServerSearchOrder"] = new string[] { dns }; mo.InvokeMethod("SetDNSServerSearchOrder", mboDNS, null); return true; } catch (Exception e) { return false; } } |
现有答案的代码很糟糕。 DNS方法根本不起作用。这是我用来配置 NIC 的代码:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 | public static class NetworkConfigurator { /// <summary> /// Set's a new IP Address and it's Submask of the local machine /// </summary> /// <param name="ipAddress">The IP Address</param> /// <param name="subnetMask">The Submask IP Address</param> /// <param name="gateway">The gateway.</param> /// <param name="nicDescription"></param> /// <remarks>Requires a reference to the System.Management namespace</remarks> public static void SetIP(string nicDescription, string[] ipAddresses, string subnetMask, string gateway) { using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (var networkConfigs = networkConfigMng.GetInstances()) { foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription)) { using (var newIP = managementObject.GetMethodParameters("EnableStatic")) { // Set new IP address and subnet if needed if (ipAddresses != null || !String.IsNullOrEmpty(subnetMask)) { if (ipAddresses != null) { newIP["IPAddress"] = ipAddresses; } if (!String.IsNullOrEmpty(subnetMask)) { newIP["SubnetMask"] = Array.ConvertAll(ipAddresses, _ => subnetMask); } managementObject.InvokeMethod("EnableStatic", newIP, null); } // Set mew gateway if needed if (!String.IsNullOrEmpty(gateway)) { using (var newGateway = managementObject.GetMethodParameters("SetGateways")) { newGateway["DefaultIPGateway"] = new[] { gateway }; newGateway["GatewayCostMetric"] = new[] { 1 }; managementObject.InvokeMethod("SetGateways", newGateway, null); } } } } } } } /// <summary> /// Set's the DNS Server of the local machine /// </summary> /// <param name="nic">NIC address</param> /// <param name="dnsServers">Comma seperated list of DNS server addresses</param> /// <remarks>Requires a reference to the System.Management namespace</remarks> public static void SetNameservers(string nicDescription, string[] dnsServers) { using (var networkConfigMng = new ManagementClass("Win32_NetworkAdapterConfiguration")) { using (var networkConfigs = networkConfigMng.GetInstances()) { foreach (var managementObject in networkConfigs.Cast<ManagementObject>().Where(mo => (bool)mo["IPEnabled"] && (string)mo["Description"] == nicDescription)) { using (var newDNS = managementObject.GetMethodParameters("SetDNSServerSearchOrder")) { newDNS["DNSServerSearchOrder"] = dnsServers; managementObject.InvokeMethod("SetDNSServerSearchOrder", newDNS, null); } } } } } } |