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 提要。我可能会在今天晚些时候或周一稍作清理后把它弄起来。
- 我希望你不介意我给你发一个例子,但这确实是一个完美的例子:http://www.codeproject.com/KB/cs/oazswitchnetconfig.aspx
几分钟就搞定了:
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 foreach (ManagementObject objMO in objMOC) newIP[“IPAddress”] = new string[] { ip_address }; setIP = objMO.InvokeMethod(“EnableStatic”, newIP, null); public void setGateway(string gateway) foreach (ManagementObject objMO in objMOC) newGateway[“DefaultIPGateway”] = new string[] { gateway }; setGateway = objMO.InvokeMethod(“SetGateways”, newGateway, null); public void setDNS(string NIC, string DNS) foreach (ManagementObject objMO in objMOC) public void setWINS(string NIC, string priWINS, string secWINS) foreach (ManagementObject objMO in objMOC) setWINS = objMO.InvokeMethod(“SetWINSServer”, wins, null); |
- 就像 EnableStatic 一样,有没有办法以编程方式将 IP 切换回动态?启用动态?我想构建一个工具,一键在静态和动态 IP 之间切换。谢谢。
- 对于那些感兴趣的人,您可以在此处找到此 ManagementObject 的所有属性和方法的列表:msdn.microsoft.com/en-us/library/aa394217.aspx
- @balexandre 我们如何才能在有限的用户帐户下使用?
- 它对我来说工作正常,但我不明白你为什么以及如何获得返回值?我看不到任何返回类型的 InvokeMethod
- @aalaap 你可以使用 EnableDHCP
- @Eric我不相信你可以,因为你需要管理员权限。
- 如果其他人想知道,要将 DNS 服务器重置为”自动”,只需将 DNSSearverSearchOrder 设置为 null。例如newDNS[“DNSServerSearchOrder”] = null;
- 注意:您必须在项目中添加对 System.Management 的引用。
- 如果您收到”BadImageFormatException””无法加载要执行的参考程序集”,则意味着您需要将项目(在配置管理器下)设置为以 x86 运行。就我而言,我正在编写一个 NetCore 控制台应用程序,并且需要进行此更改。
- 很好地抓住了@D.Squire,但话又说回来,当我写答案时没有.NET Core :) …已经有一段时间了,呵呵
- 最好检查 InvokeMethod 方法调用的返回值。例如,对于 setIP,使用 setIP[“ReturnValue”] 来获取返回值。
稍微重构了 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)) managementObject.InvokeMethod(“EnableStatic”, newIP, null); // Set mew gateway if needed /// <summary> |
- setNameservers 函数中包含的参数”nic”是什么?
- 它是网络接口的名称(描述)。您可以使用 NetworkInterface.GetAllNetworkInterfaces() 枚举它们。
- 注意:您必须在项目中添加对 System.Management 的引用。
我喜欢 WMILinq 解决方案。虽然不能完全解决您的问题,但请在下面找到它的味道:
1
2 3 4 5 6 7 8 9 10 11 12 |
using (WmiContext context = new WmiContext(@”\\\\.”)) {
context.ManagementScope.Options.Impersonation = ImpersonationLevel.Impersonate; var dnss = from nic in context.Source<Win32_NetworkAdapterConfiguration>() var ips = from s in dnss.SelectMany(dns => dns.DNSServerSearchOrder) |
http://www.codeplex.com/linq2wmi
更明确的解决方案是使用命令 netsh 更改 IP(或将其设置回 DHCP)
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) var process = new Process public bool SetDHCP(string networkInterfaceName) if (isDHCPenabled) var process = new Process |
- 这并不能回答问题……这只是滥用 netsh 和外部进程,没有任何错误处理可能会得到你的目标……在本地做这件事有点困难,但值得付出额外的努力。
建立在此处其他答案之上的更简洁的示例。我利用 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 using (var networkConfigMng = new ManagementClass(“Win32_NetworkAdapterConfiguration”)) return nics.ToArray(); /// <summary> using (NetworkAdapterConfiguration config = new NetworkAdapterConfiguration(mboDNS)) return false; /// <summary> /// <summary> return null; /// <summary> // Set mew gateway if needed } |
完整来源:
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 //Set Gateway //Set DNS return true; |
现有答案的代码很糟糕。 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)) managementObject.InvokeMethod(“EnableStatic”, newIP, null); // Set mew gateway if needed /// <summary> |
来源:https://www.codenong.com/209779/