refactor: 枚举移入Models目录,命名空间更新为Rainbow.Entity.Models
大石头 authored at 2026-07-02 12:54:58
3.13 KiB
RainbowBridge
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;
    }
}