如何在C#/.NET中查找本地计算机的FQDN?

95

如何在C#中获取本地计算机的完全限定域名(FQDN)?

13个回答

151

注意:此解决方案仅适用于针对.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的回答更简洁,所以我决定对答案添加一些注释。

最重要的是要注意,我提供的代码不等同于以下代码:

Dns.GetHostEntry("LocalHost").HostName

通常情况下,当计算机联网并且是域的一部分时,这两种方法通常会产生相同的结果,但在其他场景中,结果将有所不同。

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

如果查找计算机 FQDN 的目的是为了记录信息或生成报告,则此区别非常重要。大多数情况下,我在日志或报告中使用此方法,随后将其用于将信息映射回特定计算机。如果计算机未连接到网络,则 localhost 标识符是无用的,而名称提供所需的信息。

因此,对于每个用户来说,哪种方法更适合他们的应用程序取决于他们需要什么结果。但是说这个答案不够简明扼要是肤浅的。

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


2
使用 Dns.GetHostEntry("LocalHost").HostName,我总是得到带有主域后缀的主机名(而不是 NetBIOS)。这与计算机是否属于域、DNS 服务器是否可达或网络是否连接无关。也许我没有理解您的解释,但结果符合我的预期。(机器:W2008R2;.net 4.0;NetBIOS 名称:TESTNAME-VERYLO 主机名:TESTNAME-VERYLONG) - marsh-wiggle
2
EndsWith检查对于以与域名相同的字母结尾的主机名(例如,在域OST中的主机MYHOST)是有问题的,应该改为EndsWith("." + domainName) - user3391859
通常域名的格式为“DOMAIN.TLD”,但是你的检查方法更好-已更新以反映。 - Mike Dinescu
有时候,Dns.GetHostEntry会出现套接字错误,即使使用了有效的IP地址。 - Pradip
9
如果 domainName 为空,则返回 hostName.。应该进行一个 !String.isNullorEmpty(domainName) 的检查。 - alaney
显示剩余6条评论

64

对 Miky D 代码的稍微简化

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

5
与“Micky D的代码”不同,如果机器不属于域,则此代码返回带有附加句点的主机名。 - Bosco
1
此外,这里使用的是 NetBIOS 名称而不是 DNS 主机名。我认为 NetBIOS 名称只适用于局域网内。 - Sam
也许在最后一行加上 .Trim(".") 以去除句末的句点(如果有的话)。 - David d C e Freitas

32

这个技巧在这篇文章中有介绍。这种方法比被接受的答案更简洁,可能比得到第二多票数的答案更可靠。请注意,据我所知,这个方法没有使用NetBIOS名称,因此适用于互联网使用。

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName

@DexterLegaspi - Sam的回答很好(我甚至自己点了赞),但它并不等同于我的答案,也不一定更好。请查看我的更新答案以获取详细信息。 - Mike Dinescu
1
@MikeDinescu 这个问题是如何获取FQDN,这意味着机器在网络上并且属于一个域。被接受的答案可以完成任务,但Sam的答案更加“精确”(用缺乏更好的术语来形容)。 - Dexter Legaspi
5
这是正确的答案!但是,你最好传递一个空字符串,像这样:Dns.GetHostEntry("").HostName,而不是使用 Dns.GetHostEntry("LocalHost").HostName - paulgutten
@paulgutten你为什么说这是正确的答案?我没看出来。 - Elliott Beach

17

这是 PowerShell 的代码,就为了好玩:

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

15

对于Framework 1.1,只需要这样简单的操作:

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

然后删除机器NETBIOS名称,以仅检索domainName


1
在2013年,GetHostByName("localhost")被弃用。VS 2010建议我使用GetHostEntry("localhost")代替,这个方法很好用。 - piedar
@piedar,你可能忽略了这是针对.NET 1.1的部分。 - Sam
我想在这个答案中添加更新的信息,因为它是最简单的,也是我最喜欢的。我可能没有滚动到足够远的位置看到你的答案,它确实使我的评论变得不必要了。 - piedar

11

您可以尝试以下方法:

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

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


5
对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主机名,因此可能不适合在互联网上使用。 - Sam

2

我将其作为一种选项来组合主机名和域名以构建报告,当未捕获到域名时添加通用文本以填充,这是客户的要求之一。

我使用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解决方案中的思路构建。

1
我们已经采用了建议的结果来使用这种方式:
return System.Net.Dns.GetHostEntry(Environment.MachineName).HostName;

然而,当计算机名称超过15个字符并使用NetBios名称时,此方法不起作用。Environment.MachineName仅返回部分名称,解析主机名返回相同的计算机名称。
经过一些研究,我们找到了解决此问题的方法:
System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).HostName

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

如果计算机名称包含非a-z、0-9、'.'和'-'字符,那么这将抛出异常,并且大多数其他建议的解决方案也会失败。因此,如果您在亚洲或类似地区有用户,则应该预期问题。GetHostName将使用'?'替换这些字符。这就是为什么我更喜欢GetHostByName("localhost").HostName,它显示实际计算机名称。 - Göran

1

我测试的所有答案都没有提供我要找的DNS后缀。以下是我的解决方案。

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

1
这会假设你只有一个可用的网络接口。大多数人都有局域网、一个或多个Wifi和甚至VPN接口。这使得“First()”成为一个非常值得怀疑的解决方案。 - Marcel Grüger

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接