【问题标题】:How can you change Network settings (IP Address, DNS, WINS, Host Name) with code in C#如何使用 C# 中的代码更改网络设置(IP 地址、DNS、WINS、主机名)
【发布时间】:2010-09-17 14:38:01
【问题描述】:

我正在为要用作其他机器备份的机器开发向导。替换现有机器时,需要设置其 IP 地址、DNS、WINS 和主机名以匹配被替换的机器。

.net (C#) 中是否有允许我以编程方式执行此操作的库?

有多个网卡,每个都需要单独设置。

编辑

感谢TimothyP 提供的示例。它让我走上了正确的道路,而且快速的回复很棒。

谢谢balexandre。你的代码很完美。我很着急,已经修改了 TimothyP 链接到的示例,但我很想早点得到你的代码。

我还开发了一个使用类似技术更改计算机名称的例程。我会在以后发布它,如果您想了解更新,请订阅此问题RSS feed。我可能会在今天晚些时候或周一稍作清理后将其恢复。

【问题讨论】:

标签: c# .net configuration networking


【解决方案1】:

几分钟就搞定了:

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);
          }
        }
      }
    } 
  }
}

【讨论】:

  • 就像 EnableStatic 一样,有没有办法以编程方式将 IP 切换回动态?启用动态?我想构建一个工具,一键在静态和动态 IP 之间切换。谢谢。
  • 感兴趣的朋友可以在这里找到这个ManagementObject的所有属性和方法的列表:msdn.microsoft.com/en-us/library/aa394217.aspx
  • @balexandre 我们如何才能在受限用户帐户下使用?
  • @aalaap 你可以使用EnableDHCP
  • 如果其他人想知道,要将 DNS 服务器重置为“自动”,只需将 DNSSearverSearchOrder 设置为 null。例如newDNS["DNSServerSearchOrder"] = null;
【解决方案2】:

稍微重构了 balexandre 的代码,以便处理对象并使用 C# 3.5+ 的新语言特性(Linq、var 等)。还将变量重命名为更有意义的名称。我还合并了一些功能,以便能够以更少的 WMI 交互进行更多配置。我删除了 WINS 代码,因为我不再需要配置 WINS。如果需要,请随意添加 WINS 代码。

对于任何人都喜欢使用重构/现代化代码的情况,我将其放回社区。​​p>

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

【讨论】:

  • setNameservers 函数中包含的参数“nic”是什么?
  • 它是网络接口的名称(描述)。您可以使用 NetworkInterface.GetAllNetworkInterfaces() 枚举它们。
  • 注意:您必须在项目中添加对 System.Management 的引用。
【解决方案3】:

我喜欢 WMILinq 解决方案。虽然不能完全解决您的问题,但请在下面找到它的味道:

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

【讨论】:

    【解决方案4】:

    更明确的解决方案是使用命令netsh 更改 IP(或将其设置回 DHCP)

    netsh interface ip set address "Local Area Connection" static 192.168.0.10 255.255.255.0
    

    其中“本地连接”是网络适配器的名称。您可以在 windows 网络连接中找到它,有时它只是简单地命名为“以太网”。

    这里有两种设置IP的方法,也可以将IP设置回DHCP“自动获取IP地址”

    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;
    }
    

    【讨论】:

    • 这没有回答问题...这只是滥用 netsh 和外部进程,没有任何错误处理可能会得到您的目标...在本地进行操作有点困难但值得额外的努力。
    【解决方案5】:

    建立在此处其他答案之上的更简洁的示例。我利用 Visual Studio 附带的代码生成来删除大部分额外的调用代码,并将其替换为类型化对象。

        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

    【讨论】:

      【解决方案6】:

      现有答案的代码非常混乱。 DNS方法根本不起作用。这是我用来配置网卡的代码:

      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);
                          }
                      }
                  }
              }
          }
      }
      

      【讨论】:

        【解决方案7】:

        这可能更清楚:

        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;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2021-10-08
          • 2014-02-26
          • 2021-11-02
          • 2019-06-21
          • 2013-08-17
          • 2022-06-11
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多