using System;
using System.Diagnostics;
using System.Threading.Tasks;
namespace Rainbow.Services;
/// <summary>Windows DNS 配置管理器。通过 PowerShell 设置网口 DNS 服务器</summary>
public class WindowsDnsConfig
{
/// <summary>为指定网口设置 DNS 服务器地址</summary>
/// <param name="interfaceName">网口名称,如"以太网"</param>
/// <param name="primaryDns">主 DNS 服务器 IP</param>
/// <param name="secondaryDns">备 DNS 服务器 IP,可选</param>
/// <returns>是否成功</returns>
public async Task<Boolean> SetDnsServersAsync(String interfaceName, String primaryDns, String? secondaryDns = null)
{
try
{
var addresses = secondaryDns != null
? $"\"{primaryDns}\",\"{secondaryDns}\""
: $"\"{primaryDns}\"";
var cmd = $"-Command \"Set-DnsClientServerAddress -InterfaceAlias '{interfaceName}' -ServerAddresses ({addresses})\"";
return await RunPowerShellAsync(cmd);
}
catch
{
return false;
}
}
/// <summary>重置网口 DNS 为 DHCP 自动获取</summary>
/// <param name="interfaceName">网口名称</param>
/// <returns>是否成功</returns>
public async Task<Boolean> ResetDnsToDhcpAsync(String interfaceName)
{
try
{
var cmd = $"-Command \"Set-DnsClientServerAddress -InterfaceAlias '{interfaceName}' -ResetServerAddresses\"";
return await RunPowerShellAsync(cmd);
}
catch
{
return false;
}
}
/// <summary>获取当前 DNS 服务器地址</summary>
/// <param name="interfaceName">网口名称</param>
/// <returns>DNS 服务器列表,包含 IPv4 和 IPv6 地址</returns>
public async Task<String> GetDnsServersAsync(String interfaceName)
{
try
{
var cmd = $"-Command \"(Get-DnsClientServerAddress -InterfaceAlias '{interfaceName}' -AddressFamily IPv4).ServerAddresses -join ','\"";
var psi = new ProcessStartInfo("powershell", cmd)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using var proc = Process.Start(psi);
if (proc == null) return "";
var output = await proc.StandardOutput.ReadToEndAsync();
await proc.WaitForExitAsync().WaitAsync(TimeSpan.FromSeconds(10));
return (output ?? "").Trim();
}
catch
{
return "";
}
}
private static async Task<Boolean> RunPowerShellAsync(String arguments)
{
var psi = new ProcessStartInfo("powershell", arguments)
{
RedirectStandardOutput = true,
RedirectStandardError = true,
UseShellExecute = false,
CreateNoWindow = true,
};
using var proc = Process.Start(psi);
if (proc == null) return false;
await proc.WaitForExitAsync().WaitAsync(TimeSpan.FromSeconds(15));
return proc.ExitCode == 0;
}
}
|