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

如何在 C # 中获得本地机器的 FQDN?

82957 次浏览

NOTE: This solution only works when targeting the .NET 2.0 (and newer) frameworks.

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
}

UPDATE

Since a lot of people have commented that Sam's Answer is more concise I've decided to add some comments to the answer.

The most important thing to note is that the code I gave is not equivalent to the following code:

Dns.GetHostEntry("LocalHost").HostName

While in the general case when the machine is networked and part of a domain, both methods will generally produce the same result, in other scenarios the results will differ.

A scenario where the output will be different is when the machine is not part of a domain. In this case, the Dns.GetHostEntry("LocalHost").HostName will return localhost while the GetFQDN() method above will return the NETBIOS name of the host.

This distinction is important when the purpose of finding the machine FQDN is to log information, or generate a report. Most of the time I've used this method in logs or reports that are subsequently used to map information back to a specific machine. If the machines are not networked, the localhost identifier is useless, whereas the name gives the needed information.

So ultimately it's up to each user which method is better suited for their application, depending on what result they need. But to say that this answer is wrong for not being concise enough is superficial at best.

See an example where the output will be different: http://ideone.com/q4S4I0

A slight simplification of Miky D's code

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

Here it is in PowerShell, for the heck of it:

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

And for Framework 1.1 is as simple as this:

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

And then remove the machine NETBIOS name to retrieve only the domainName

If you want to tidy it up, and handle exceptions, try this:

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;
}

A slight improvement on Matt Z's answer so that a trailing full stop isn't returned if the computer is not a member of a domain:

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

This is covered by this article. This technique is more brief than the accepted answer and probably more reliable than the next most-voted answer. Note that as far as I understand, this doesn't use NetBIOS names, so it should be suitable for Internet use.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName

You can try the following:

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

This shoud give you the FQDN of the current local machine (or you can specify any host).

Used this as one of my options to combine host name and domain name for building a report, added the generic text to fill in when domain name was not captured, this was one of the customers requirements.

I tested this using 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
}

Built using ideas from Miky Dinescu solution.

We have implemented suggested result to use this way:

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

However, turned out that this does not work right when computer name is longer than 15 characters and using NetBios name. The Environment.MachineName returns only partial name and resolving host name returns same computer name.

After some research we found a solution to fix this problem:

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

This resolved all problems including computer name.

I've used this approach:

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

None of the answers provided that I tested actually provided the DNS suffix I was looking for. Here's what I came up with.

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

My collection of methods to handle all cases around FQ Hostname / Hostname / NetBIOS Machinename / DomainName

    /// <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;
}