【问题标题】:How to find FQDN of local machine in C#/.NET ?如何在 C#/.NET 中查找本地机器的 FQDN?
【发布时间】:2010-10-22 17:26:18
【问题描述】:

如何在 C# 中获取本地计算机的 FQDN?

【问题讨论】:

    标签: c# localhost fqdn


    【解决方案1】:

    注意:此解决方案仅适用于 .NET 2.0(和更新的)框架。

    using System;
    using System.Net;
    using System.Net.NetworkInformation;
    //...
    
    public static string GetFQDN()
    {
        string domainName = IPGlobalProperties.GetIPGlobalProperties().DomainName;
        string hostName = Dns.GetHostName();
    
        domainName = "." + domainName;
        if(!hostName.EndsWith(domainName))  // if hostname does not already include domain name
        {
            hostName += domainName;   // add the domain name part
        }
    
        return hostName;                    // return the fully qualified name
    }
    

    更新

    由于很多人评论说Sam's Answer 更简洁,我决定在答案中添加一些 cmets。

    需要注意的最重要的一点是,我给出的代码与以下代码不等价

    Dns.GetHostEntry("LocalHost").HostName
    

    虽然在机器联网且属于域的一般情况下,这两种方法通常会产生相同的结果,但在其他情况下,结果会有所不同。

    当机器不是域的一部分时,输出会有所不同。在这种情况下,Dns.GetHostEntry("LocalHost").HostName 将返回 localhost,而上面的 GetFQDN() 方法将返回主机的 NETBIOS 名称。

    当查找机器 FQDN 的目的是记录信息或生成报告时,这种区别很重要。大多数时候,我在日志或报告中使用此方法,这些日志或报告随后用于将信息映射回特定机器。如果机器没有联网,localhost 标识符是无用的,而名称提供了所需的信息。

    因此,最终取决于每个用户,哪种方法更适合他们的应用程序,具体取决于他们需要的结果。但是说这个答案不够简洁是错误的,充其量是肤浅的。

    查看输出不同的示例:http://ideone.com/q4S4I0

    【讨论】:

    • 使用 Dns.GetHostEntry("LocalHost").HostName 我总是得到带有主域后缀的主机名(不是 netbios)。这与机器是否属于域、DNS 服务器是否可访问或网络是否已连接无关。可能我不明白你的解释,但结果是我所期望的。 (机器:W2008R2;.net 4.0;netbiosname:TESTNAME-VERYLO 主机名:TESTNAME-VERYLONG)
    • 为什么你使用Dns.GetHostName() 代替hostName 而不是使用你已经拥有的IPGlobalProperties 对象的HostName 属性,上面一行?
    • @Xharlie 因为IPGlobalProperties 主机名属性返回NetBIOS 名称,而Dns.GetHostName() 返回DNS 主机名。
    • EndsWith 对以与域名相同字母结尾的主机名(例如域 OST 中的主机 MYHOST)的检查无效,应该是 EndsWith("." + domainName)
    • 如果 domainName 为空,则返回 hostName.。应该有一个!String.isNullorEmpty(domainName) 检查
    【解决方案2】:

    Miky D 的代码稍微简化

        public static string GetLocalhostFqdn()
        {
            var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            return string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
        }
    

    【讨论】:

    • 与 Micky D 的代码不同,如果机器不是域的成员,它会返回带有句号的主机名。
    • 另外,这使用 NetBIOS 名称而不是 DNS 主机名。我相信 NetBIOS 名称只适用于 LAN。
    • 也许在最后一行添加一个.Trim(".") 以摆脱 .如果存在。
    【解决方案3】:

    this article 对此进行了介绍。这种技术比公认的答案更简短,并且可能比下一个投票最多的答案更可靠。请注意,据我了解,这使用 NetBIOS 名称,所以它应该适合 Internet 使用。

    .NET 2.0+

    Dns.GetHostEntry("LocalHost").HostName
    

    .NET 1.0 - 1.1

    Dns.GetHostByName("LocalHost").HostName
    

    【讨论】:

    • @DexterLegaspi - Sam 的答案是一个很好的答案(我什至自己也赞成)但它并不等同于我的答案,也不一定更好。有关详细信息,请参阅我的更新答案。
    • @MikeDinescu 问题是如何获得 FQDN,这意味着机器在网络上并且是域的一部分。接受的答案可以完成工作,但 Sam 的答案更“准确”(因为没有更好的术语)
    • 这是正确答案!但不要这样做 Dns.GetHostEntry("LocalHost").HostName 你最好像这样传递一个空字符串:Dns.GetHostEntry("").HostName
    【解决方案4】:

    它在 PowerShell 中,真是太棒了:

    $ipProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
    "{0}.{1}" -f $ipProperties.HostName, $ipProperties.DomainName
    

    【讨论】:

      【解决方案5】:

      Framework 1.1 就是这么简单:

      System.Net.Dns.GetHostByName("localhost").HostName
      

      然后删除机器的 NETBIOS 名称以仅检索域名

      【讨论】:

      • 这里在 2013 年,GetHostByName("localhost") 已过时。 VS 2010 建议我改用GetHostEntry("localhost"),效果很好。
      • @piedar,你可能错过了关于 .NET 1.1 的一点。
      • 我想在这个答案中添加更新的信息,因为它是最简单的,因此是我最喜欢的。我可能滚动得不够远,看不到您的答案,这确实使我的评论变得不必要了。
      【解决方案6】:

      您可以尝试以下方法:

      return System.Net.Dns.GetHostEntry(Environment.MachineName).HostName;
      

      这应该给你当前本地机器的 FQDN(或者你可以指定任何主机)。

      【讨论】:

        【解决方案7】:

        对 Matt Z 的回答略有改进,因此如果计算机不是域的成员,则不会返回尾随句号:

        public static string GetLocalhostFqdn()
        {
            var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
            return string.IsNullOrWhiteSpace(ipProperties.DomainName) ? ipProperties.HostName : string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
        }
        

        【讨论】:

        • 注意,我认为这里使用的是 NetBIOS 主机名,因此可能不适合 Internet 使用。
        【解决方案8】:

        将此作为我的选项之一,将主机名和域名结合起来构建报告,添加通用文本以在未捕获域名时填写,这是客户要求之一。

        我使用 C# 5.0、.Net 4.5.1 对此进行了测试

        private static string GetHostnameAndDomainName()
        {
               // if No domain name return a generic string           
               string currentDomainName = IPGlobalProperties.GetIPGlobalProperties().DomainName ?? "nodomainname";
               string hostName = Dns.GetHostName();
        
            // check if current hostname does not contain domain name
            if (!hostName.Contains(currentDomainName))
            {
                hostName = hostName + "." + currentDomainName;
            }
            return hostName.ToLower();  // Return combined hostname and domain in lowercase
        } 
        

        使用来自 Miky Dinescu 解决方案的想法构建。

        【讨论】:

          【解决方案9】:

          我们已经实现了使用这种方式的建议结果:

          return System.Net.Dns.GetHostEntry(Environment.MachineName).HostName;
          

          但是,当计算机名称超过 15 个字符并使用 NetBios 名称时,这将无法正常工作。 Environment.MachineName 仅返回部分名称,解析主机名返回相同的计算机名称。

          经过一番研究,我们找到了解决此问题的解决方案:

          System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).HostName
          

          这解决了包括计算机名称在内的所有问题。

          【讨论】:

          • 这将引发异常,并且建议的大多数其他解决方案也将失败,如果您的计算机已由用户指定的名称包含非 az、0-9、'的字符。 ','-'。因此,如果您在亚洲或类似地区有用户,请期待问题。 GetHostName 会将这些字符替换为“?”。这就是为什么我更喜欢显示实际计算机名称的 GetHostByName("localhost").HostName。
          【解决方案10】:

          我测试的所有答案都没有提供我正在寻找的 DNS 后缀。这是我想出的。

          public static string GetFqdn()
          {
              var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
              var ipprops = networkInterfaces.First().GetIPProperties();
              var suffix = ipprops.DnsSuffix;
              return $"{IPGlobalProperties.GetIPGlobalProperties().HostName}.{suffix}";
          }
          

          【讨论】:

            【解决方案11】:

            我用过这种方法:

            private static string GetLocalhostFQDN()
            {
                var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
                return $"{ipProperties.HostName}.{ipProperties.DomainName}";
            }
            

            【讨论】:

              【解决方案12】:

              我收集的用于处理 FQ 主机名/主机名/NetBIOS 机器名/域名周围所有情况的方法

                  /// <summary>
                  /// Get the full qualified hostname
                  /// </summary>
                  /// <param name="throwOnMissingDomainName"></param>
                  /// <returns></returns>
                  public static string GetMachineFQHostName(bool throwOnMissingDomainName = false)
                  {
                      string domainName = GetMachineFQDomainName();
                      string hostName = GetMachineHostName();
              
                      if (string.IsNullOrEmpty(domainName) && throwOnMissingDomainName) throw new Exception($"Missing domain name on machine: { hostName }");
                      else if (string.IsNullOrEmpty(domainName)) return hostName;
                      //<----------
              
                      return $"{ hostName }.{ domainName }";
                  }
              
              
                  /// <summary>
                  /// Get the NetBIOS name of the local machine
                  /// </summary>
                  /// <returns></returns>
                  public static string GetMachineName()
                  {
                      return Environment.MachineName;
                  }
              
                  /// <summary>
                  /// Get the Hostname from the local machine which differs from the NetBIOS name when 
                  /// longer than 15 characters
                  /// </summary>
                  /// <returns></returns>
                  public static string GetMachineHostName()
                  {
                      /// I have been told that GetHostName() may return the FQName. Never seen that, but better safe than sorry ....
                      string hostNameRaw = System.Net.Dns.GetHostName();
                      return hostNameRaw.Split('.')[0];
                  }
              
                  /// <summary>
                  /// Check if hostname and NetBIOS name are equal
                  /// </summary>
                  /// <returns></returns>
                  public static bool AreHostNameAndNetBIOSNameEqual()
                  {
                      return GetMachineHostName().Equals(GetMachineName(), StringComparison.OrdinalIgnoreCase);
                  }
              
                  /// <summary>
                  /// Get the domain name without the hostname
                  /// </summary>
                  /// <returns></returns>
                  public static string GetMachineFQDomainName()
                  {
                      return IPGlobalProperties.GetIPGlobalProperties().DomainName;
                  }
              

              【讨论】:

                【解决方案13】:

                如果你想整理和处理异常,试试这个:

                public static string GetLocalhostFQDN()
                        {
                            string domainName = string.Empty;
                            try
                            {
                                domainName = NetworkInformation.IPGlobalProperties.GetIPGlobalProperties().DomainName;
                            }
                            catch
                            {
                            }
                            string fqdn = "localhost";
                            try
                            {
                                fqdn = System.Net.Dns.GetHostName();
                                if (!string.IsNullOrEmpty(domainName))
                                {
                                    if (!fqdn.ToLowerInvariant().EndsWith("." + domainName.ToLowerInvariant()))
                                    {
                                        fqdn += "." + domainName;
                                    }
                                }
                            }
                            catch
                            {
                            }
                            return fqdn;
                        }
                

                【讨论】:

                • “并处理异常” - FAIL.
                • 你认为 catch 自己会处理异常!
                • 不,我认为您要如何处理异常是您需要自己决定的事情。如果您无法取回域名,您打算如何处理?
                • 记录错误报告并警告用户出现问题,而不是向客户端代码提供错误信息。
                最近更新 更多