如何在Windows 10上使用C#更改DNS
Posted
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Windows 10上使用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操作系统上运行?
首先,您需要获取要设置/取消设置DNS的NetworkInterface
我已经在最新版本的Windows 10上测试了这段代码,它就像一个魅力!
以下是查找有源以太网或Wifi网络的代码(在大多数情况下不是100%准确但有用)
public static NetworkInterface GetActiveEthernetOrWifiNetworkInterface()
{
var Nic = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(
a => a.OperationalStatus == OperationalStatus.Up &&
(a.NetworkInterfaceType == NetworkInterfaceType.Wireless80211 || a.NetworkInterfaceType == NetworkInterfaceType.Ethernet) &&
a.GetIPProperties().GatewayAddresses.Any(g => g.Address.AddressFamily.ToString() == "InterNetwork"));
return Nic;
}
SetDNS
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);
}
}
}
}
}
UnsetDNS
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);
}
}
}
}
}
用法
SetDNS("127.0.0.1");
结合多个解决方案我发现以下代码适用于Windows 10和8.1(其他代码未经过测试,但也可以正常工作):
public static void setDNS(string NIC, string DNS)
{
ConnectionOptions options = PrepareOptions();
ManagementScope scope = PrepareScope(Environment.MachineName, options, @"
ootCIMV2");
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]的NIC-Name。
[000000] Intel(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#
以及这个问题的答案。
使用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 , @"
ootCIMV2" );
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
这是我用来执行此操作的代码,它可以工作:
/// <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 以上是关于如何在Windows 10上使用C#更改DNS的主要内容,如果未能解决你的问题,请参考以下文章
如何在 Windows 上更改 Jenkins 默认文件夹?
dig(DNS Lookup)在Windows上指定DNS服务器
在 Windows 10 Home 上使用 WSL2 上的 Docker Desktop 时,如何更改 docker 映像的位置?