C# 如何在C语言中以编程方式获取DNS后缀搜索列表#

C# 如何在C语言中以编程方式获取DNS后缀搜索列表#,c#,windows,dns,C#,Windows,Dns,如何在C#中的Windows 10计算机上获取DNS后缀搜索列表 例如,如果我在cmd中键入ipconfig,我会看到如下内容: Windows IP Configuration Host Name . . . . . . . . . . . . : BOB Primary Dns Suffix . . . . . . . : fred.george.com Node Type . . . . . . . . . . . . : Hybrid IP Routing E

如何在C#中的Windows 10计算机上获取DNS后缀搜索列表

例如,如果我在cmd中键入
ipconfig
,我会看到如下内容:

Windows IP Configuration

   Host Name . . . . . . . . . . . . : BOB
   Primary Dns Suffix  . . . . . . . : fred.george.com
   Node Type . . . . . . . . . . . . : Hybrid
   IP Routing Enabled. . . . . . . . : No
   WINS Proxy Enabled. . . . . . . . : No
   DNS Suffix Search List. . . . . . : fred.com
                                       george.com

我想得到一个“fred.com”和“george.com”的数组。我尝试了几种不同的方法[1],但它们使用adapters属性(为空)


[1]

域后缀存储在注册表中:

System\CurrentControlSet\Services\Tcpip\Parameters
SearchList (REG_SZ)
这些设置是计算机的全局设置(所有适配器和所有ip地址(IPv4和IPv6))

使用以下代码获取字符串:

string searchList = "";
try
{
    using (var reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(tcpSettingsSubKey))
    {
        searchList = (reg.GetValue("SearchList") as string);
    }
}
catch(Exception ex)
{
    // something went wrong
}
我编写这个类是为了获得更多这些设置。在这个类中,后缀存储在
DNSSearchListString
DNSSearchList

using System;
using System.Linq;

/// <summary>
/// Retrieving some IP settings from the registry.
/// The default dns suffix is not stored there but cat be read from:
/// <see cref="System.Net.NetworkInformation.IPInterfaceProperties.DnsSuffix"/>
/// </summary>
public static class LocalMachineIpSettings
{
    private readonly static object dataReadLock = new object();
    private static bool dataReadFinished = false;

    private static string domain;
    private static string hostname;
    private static int? iPEnableRouter;

    /// <summary>
    /// Search list (the suffixes) as stored in registry
    /// </summary>
    private static string searchListString;

    /// <summary>
    /// Search list (the suffixes) as string array
    /// </summary>
    private static string[] searchList;

    /// <summary>
    /// also available at: <see cref="System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties()"/>
    /// </summary>
    public static string Domain { get { ReadValues(); return domain; } }
    /// <summary>
    /// also available at: <see cref="System.Net.NetworkInformation.IPGlobalProperties.GetIPGlobalProperties()"/>
    /// </summary>
    public static string Hostname { get { ReadValues(); return hostname; } }
    public static int? IPEnableRouter { get { ReadValues(); return iPEnableRouter; } }
    public static string[] DNSSearchList { get { ReadValues(); return searchList; } }
    public static string DNSSearchListString { get { ReadValues(); return searchListString; } }

    private static void ReadValues()
    {
        lock (dataReadLock)
        {
            if (dataReadFinished == true)
            {
                return;
                //<----------
            }

            ForceRefresh();
        }
    }

    /// <summary>
    /// Reread the values
    /// </summary>
    public static void ForceRefresh()
    {
        const string tcpSettingsSubKey = @"System\CurrentControlSet\Services\Tcpip\Parameters";

        lock (dataReadLock)
        {
            try
            {
                Microsoft.Win32.RegistryKey reg = null;
                using (reg = Microsoft.Win32.Registry.LocalMachine.OpenSubKey(tcpSettingsSubKey))
                {
                    domain = (reg.GetValue("Domain") as string);
                    hostname = (reg.GetValue("Hostname") as string);
                    iPEnableRouter = (reg.GetValue("IPEnableRouter") as int?);
                    searchListString = (reg.GetValue("SearchList") as string);
                    searchList = searchListString?.Split(new[] { ' ', ',', ';' }, StringSplitOptions.RemoveEmptyEntries).Select(o => o.Trim(' ', '.')).ToArray();
                }

                dataReadFinished = true;
            }
            catch (Exception ex)
            {
                throw new InvalidOperationException($"Cannot access HKLM\\{ tcpSettingsSubKey } or values beneath see inner exception for details", ex);
                //<----------
            }
        }
    }
}
使用系统;
使用System.Linq;
/// 
///正在从注册表中检索某些IP设置。
///默认dns后缀不存储在此处,但可以从以下位置读取:
/// 
/// 
公共静态类LocalMachineIpSettings
{
私有只读静态对象dataReadLock=新对象();
私有静态bool dataReadFinished=false;
私有静态字符串域;
私有静态字符串主机名;
私有静态int?iPEnableRouter;
/// 
///存储在注册表中的搜索列表(后缀)
/// 
私有静态字符串searchListString;
/// 
///搜索列表(后缀)作为字符串数组
/// 
私有静态字符串[]搜索列表;
/// 
///也可从以下网址获得:
/// 
公共静态字符串域{get{ReadValues();返回域;}}
/// 
///也可从以下网址获得:
/// 
公共静态字符串主机名{get{ReadValues();返回主机名;}}
公共静态int?IPEnableRouter{get{ReadValues();返回IPEnableRouter;}}
公共静态字符串[]DNSSearchList{get{ReadValues();返回searchList;}}
公共静态字符串DNSSearchListString{get{ReadValues();返回searchListString;}}
私有静态void ReadValues()
{
锁(数据读取锁)
{
如果(dataReadFinished==true)
{
返回;
//o.Trim('').ToArray();
}
dataReadFinished=true;
}
捕获(例外情况除外)
{
抛出新的InvalidOperationException($“无法访问HKLM\\{tcpSettingsSubKey}或下面的值,请参阅内部异常以了解详细信息”,ex);

//为什么不直接运行这个命令,并提取那些行呢?你可能会找到灵感,但我会使用BugFinder——构建正确的列表是复杂的,因为信息是动态的而不是静态的。