如何在Windows 10上使用C#更改DNS

时间:2016-10-27 18:03:32

标签: c# dns

我正在尝试通过VB.NET更改Windows 10上的DNS。

我的代码适用于Windows 7,但它无法在Windows 10上运行。

以下是我更改DNS的Windows 7代码:

ManagementClass mc = new ManagementClass("Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
    if ((bool)mo["IPEnabled"])
    {
        ManagementBaseObject objdns = mo.GetMethodParameters("SetDNSServerSearchOrder");
        if (objdns != null)
        {
            string[] s = { "192.168.XX.X", "XXX.XX.X.XX" };
            objdns["DNSServerSearchOrder"] = s;
            mo.InvokeMethod("SetDNSServerSearchOrder", objdns, null);

我的问题是,如何让它在Windows 10操作系统上运行?

4 个答案:

答案 0 :(得分:3)

首先,您需要获取要设置/取消设置DNS的NetworkInterface

我已经在最新版本的Windows 10上测试了这段代码,它就像一个魅力!

以下是查找有源以太网或Wifi网络的代码(在大多数情况下不是100%准确但很有用)

public static void SetDNS(string DnsString)
{
    string[] Dns = { DnsString };
    var CurrentInterface = GetActiveEthernetOrWifiNetworkInterface();
    if (CurrentInterface == null) return;

    ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
    ManagementObjectCollection objMOC = objMC.GetInstances();
    foreach (ManagementObject objMO in objMOC)
    {
        if ((bool)objMO["IPEnabled"])
        {
            if (objMO["Caption"].ToString().Contains(CurrentInterface.Description))
            {
                ManagementBaseObject objdns = objMO.GetMethodParameters("SetDNSServerSearchOrder");
                if (objdns != null)
                {
                    objdns["DNSServerSearchOrder"] = Dns;
                    objMO.InvokeMethod("SetDNSServerSearchOrder", objdns, null);
                }
            }
        }
    }
}

<强> SetDNS

public static void UnsetDNS()
{
    var CurrentInterface = GetActiveEthernetOrWifiNetworkInterface();
        if (CurrentInterface == null) return;

    ManagementClass objMC = new ManagementClass("Win32_NetworkAdapterConfiguration");
    ManagementObjectCollection objMOC = objMC.GetInstances();
    foreach (ManagementObject objMO in objMOC)
    {
        if ((bool)objMO["IPEnabled"])
        {
            if (objMO["Caption"].ToString().Contains(CurrentInterface.Description))
            {
                ManagementBaseObject objdns = objMO.GetMethodParameters("SetDNSServerSearchOrder");
                if (objdns != null)
                {
                    objdns["DNSServerSearchOrder"] = null;
                    objMO.InvokeMethod("SetDNSServerSearchOrder", objdns, null);
                }
            }
        }
    }
}

<强> UnsetDNS

SetDNS("127.0.0.1");

<强>用法

tabBetterLife

答案 1 :(得分:2)

结合多个解决方案我发现以下代码适用于Windows 10和8.1(其他代码未经过测试,但也可以正常工作):

public static void setDNS(string NIC, string DNS)
{
    ConnectionOptions options = PrepareOptions();
    ManagementScope scope = PrepareScope(Environment.MachineName, options, @"\root\CIMV2");
    ManagementPath managementPath = new ManagementPath("Win32_NetworkAdapterConfiguration");
    ObjectGetOptions objectGetOptions = new ObjectGetOptions();
    ManagementClass mc = new ManagementClass(scope, managementPath, objectGetOptions);
    ManagementObjectCollection moc = mc.GetInstances();
    foreach (ManagementObject mo in moc)
    {
        if ((bool)mo["IPEnabled"])
        {
            if (mo["Caption"].ToString().Contains(NIC))
            {
                try
                {
                    ManagementBaseObject newDNS = mo.GetMethodParameters("SetDNSServerSearchOrder");
                    newDNS["DNSServerSearchOrder"] = DNS.Split(',');
                    ManagementBaseObject setDNS = mo.InvokeMethod("SetDNSServerSearchOrder", newDNS, null);
                }
                catch (Exception e)
                {
                    Console.WriteLine(e.ToString());
                    Console.ReadKey();
                    throw;
                }
            }
        }
    }
}

应用程序需要以提升的权限运行(在我的情况下,我开始运行.exe的提升进程):

private void callSwapDNS(string NIC, string DNS)
{
    const int ERROR_CANCELLED = 1223; //The operation was canceled by the user.
    ProcessStartInfo info = new ProcessStartInfo(@"swap.exe");
    string wrapped = string.Format(@"""{0}"" ""{1}""", NIC, DNS);
    info.Arguments = wrapped;
    info.UseShellExecute = true;
    info.Verb = "runas";
    info.WindowStyle = ProcessWindowStyle.Hidden;
    try
    {
        Process.Start(info);
        Thread.Sleep(500);
    }
    catch (Win32Exception ex)
    {
        if (ex.NativeErrorCode == ERROR_CANCELLED)
            MessageBox.Show("Why you no select Yes?");
        else
            throw;
    }
}

使用mo["Caption"].ToString().Contains(NIC)不适用于Windows 10,因为WMI查询返回带有[000000]的网卡名称

  

[000000]英特尔(R)82574L千兆网络连接

在我的Windows 10计算机上。

归功于以下答案:[升级到Windows 10后WMI无法正常工作

WMI not working after upgrading to Windows 10
How can you change Network settings (IP Address, DNS, WINS, Host Name) with code in C#

以及这个问题的答案。

答案 2 :(得分:0)

使用Windows 10,您可能需要先进行身份验证。将ConnectionOptions实例传递给ManagementScope构造函数,定义Authentication和Impersonation属性。

试试这个:

// Method to prepare the WMI query connection options.
public static ConnectionOptions PrepareOptions ( )
{
  ConnectionOptions options = new ConnectionOptions ( );
  options . Impersonation = ImpersonationLevel . Impersonate;
  options . Authentication = AuthenticationLevel . Default;
  options . EnablePrivileges = true;
  return options;
}

// Method to prepare WMI query management scope.
public static ManagementScope PrepareScope ( string machineName , ConnectionOptions options , string path  )
{
  ManagementScope scope = new ManagementScope ( );
  scope . Path = new ManagementPath ( @"\\" + machineName + path );
  scope . Options = options;
  scope . Connect ( );
  return scope;
}

// Set DNS.
ConnectionOptions options = PrepareOptions ( );
ManagementScope scope = PrepareScope ( Environment . MachineName , options , @"\root\CIMV2" );
ManagementClass mc = new ManagementClass(scope, "Win32_NetworkAdapterConfiguration");
ManagementObjectCollection moc = mc.GetInstances();
foreach (ManagementObject mo in moc)
{
    if ((bool)mo["IPEnabled"])
    {
        ManagementBaseObject objdns = mo.GetMethodParameters("SetDNSServerSearchOrder");
        if (objdns != null)
        {
            string[] s = { "192.168.XX.X", "XXX.XX.X.XX" };
            objdns["DNSServerSearchOrder"] = s;
            mo.InvokeMethod("SetDNSServerSearchOrder", objdns, null);

基于这个答案:

WMI not working after upgrading to Windows 10

答案 3 :(得分:0)

这是我用来执行此操作的代码,它可以工作:

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

希望它有所帮助...