2008-10-16 180 views
57

我正在開發一個嚮導,用於作爲其他機器的備份使用的機器。當它替換現有的機器時,它需要設置其IP地址,DNS,WINS和主機名稱以匹配被更換的機器。如何用C#中的代碼更改網絡設置(IP地址,DNS,WINS,主機名)

在.net(C#)中有一個庫,它允許我以編程方式執行此操作嗎?

有多個網卡,每個需要單獨設置。

編輯

謝謝TimothyP爲您的例子。它讓我走上正確的軌道,快速回復真棒。

謝謝balexandre。你的代碼是完美的。我很匆忙,已經修改了TimothyP鏈接的例子,但是我希望能夠儘早使用您的代碼。

我也開發了一個使用類似技術來改變計算機名稱的例程。我將在未來發布,因此如果您想要了解更新,請訂閱此問題RSS feed。我可能會在今天晚些時候或在星期一清理完一些後才能清理它。

回答

77

就在幾分鐘內做出這樣的:

using System; 
using System.Management; 

namespace WindowsFormsApplication_CS 
{ 
    class NetworkManagement 
    { 
     /// <summary> 
     /// Set's a new IP Address and it's Submask of the local machine 
     /// </summary> 
     /// <param name="ip_address">The IP Address</param> 
     /// <param name="subnet_mask">The Submask IP Address</param> 
     /// <remarks>Requires a reference to the System.Management namespace</remarks> 
     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"]) 
       { 
        try 
        { 
         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); 
        } 
        catch (Exception) 
        { 
         throw; 
        } 


       } 
      } 
     } 
     /// <summary> 
     /// Set's a new Gateway address of the local machine 
     /// </summary> 
     /// <param name="gateway">The Gateway IP Address</param> 
     /// <remarks>Requires a reference to the System.Management namespace</remarks> 
     public void setGateway(string gateway) 
     { 
      ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration"); 
      ManagementObjectCollection objMOC = objMC.GetInstances(); 

      foreach (ManagementObject objMO in objMOC) 
      { 
       if ((bool)objMO["IPEnabled"]) 
       { 
        try 
        { 
         ManagementBaseObject setGateway; 
         ManagementBaseObject newGateway = 
          objMO.GetMethodParameters("SetGateways"); 

         newGateway["DefaultIPGateway"] = new string[] { gateway }; 
         newGateway["GatewayCostMetric"] = new int[] { 1 }; 

         setGateway = objMO.InvokeMethod("SetGateways", newGateway, null); 
        } 
        catch (Exception) 
        { 
         throw; 
        } 
       } 
      } 
     } 
     /// <summary> 
     /// Set's the DNS Server of the local machine 
     /// </summary> 
     /// <param name="NIC">NIC address</param> 
     /// <param name="DNS">DNS server address</param> 
     /// <remarks>Requires a reference to the System.Management namespace</remarks> 
     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)) 
        { 
         try 
         { 
          ManagementBaseObject newDNS = 
           objMO.GetMethodParameters("SetDNSServerSearchOrder"); 
          newDNS["DNSServerSearchOrder"] = DNS.Split(','); 
          ManagementBaseObject setDNS = 
           objMO.InvokeMethod("SetDNSServerSearchOrder", newDNS, null); 
         } 
         catch (Exception) 
         { 
          throw; 
         } 
        } 
       } 
      } 
     } 
     /// <summary> 
     /// Set's WINS of the local machine 
     /// </summary> 
     /// <param name="NIC">NIC Address</param> 
     /// <param name="priWINS">Primary WINS server address</param> 
     /// <param name="secWINS">Secondary WINS server address</param> 
     /// <remarks>Requires a reference to the System.Management namespace</remarks> 
     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)) 
        { 
         try 
         { 
          ManagementBaseObject setWINS; 
          ManagementBaseObject wins = 
          objMO.GetMethodParameters("SetWINSServer"); 
          wins.SetPropertyValue("WINSPrimaryServer", priWINS); 
          wins.SetPropertyValue("WINSSecondaryServer", secWINS); 

          setWINS = objMO.InvokeMethod("SetWINSServer", wins, null); 
         } 
         catch (Exception) 
         { 
          throw; 
         } 
        } 
       } 
      } 
     } 
    } 
} 
+3

就像EnableStatic一樣,有沒有什麼辦法可以通過編程方式將IP切換回動態? EnableDynamic?我想要構建一個工具,只需點擊一下即可在靜態和動態IP之間切換。謝謝。 – aalaap 2011-11-08 07:48:41

+6

對於那些感興趣的人,你可以在這裏找到這個管理對象的所有屬性和方法的列表:http://msdn.microsoft.com/en-us/library/aa394217.aspx – Paccc 2012-12-19 18:36:16

+1

@balexandre我們如何才能在有限的條件下工作用戶帳號? – Eric 2013-01-02 12:35:12

5

我喜歡WMILinq解決方案。雖然沒有完全解決您的問題,在下面找到它的口味:這樣的對象被設置在從balexandre一點重構代碼

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

23

和C#3.5 +新的語言功能的使用(Linq,var等)。還將變量重命名爲更有意義的名稱。我還合併了一些功能,以便能夠以較少的WMI交互進行更多配置。我刪除了WINS代碼,因爲我不再需要配置WINS。如果需要,隨意添加WINS代碼。

對於任何人喜歡使用重構/現代化的代碼,我把它放回社區在這裏。在C#

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

現有的答案有相當斷碼。 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); 
        } 
       } 
      } 
     } 
    } 
} 
0

一個是建立在這裏的其他答案的頂部略有更簡潔的例子。我利用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

相關問題