Como encontrar o FQDN da máquina local em C # / .net?

87

Como você pode obter o FQDN de uma máquina local em C #?

Sam
fonte

Respostas:

142

OBSERVAÇÃO: Esta solução só funciona quando direcionada às estruturas .NET 2.0 (e mais recentes).

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
}

ATUALIZAR

Como muitas pessoas comentaram que a resposta de Sam é mais concisa, decidi adicionar alguns comentários à resposta.

O mais importante a notar é que o código que dei não é equivalente ao seguinte código:

Dns.GetHostEntry("LocalHost").HostName

Enquanto, no caso geral, quando a máquina está em rede e faz parte de um domínio, ambos os métodos geralmente produzem o mesmo resultado, em outros cenários os resultados serão diferentes.

Um cenário em que a saída será diferente é quando a máquina não faz parte de um domínio. Nesse caso, o Dns.GetHostEntry("LocalHost").HostNameretornará localhostenquanto o GetFQDN()método acima retornará o nome NETBIOS do host.

Essa distinção é importante quando o objetivo de localizar o FQDN da máquina é registrar informações ou gerar um relatório. Na maioria das vezes, usei esse método em logs ou relatórios que são subsequentemente usados ​​para mapear informações de volta para uma máquina específica. Se as máquinas não estiverem em rede, o localhostidentificador é inútil, enquanto o nome fornece as informações necessárias.

Portanto, em última análise, cabe a cada usuário qual método é mais adequado para sua aplicação, dependendo do resultado de que precisam. Mas dizer que essa resposta está errada por não ser concisa o suficiente é superficial, na melhor das hipóteses.

Veja um exemplo em que a saída será diferente: http://ideone.com/q4S4I0

Mike Dinescu
fonte
2
Usando Dns.GetHostEntry("LocalHost").HostNamesempre obtenho o nome do host (não netbios) com o sufixo do domínio primário. Isso não depende se a máquina faz parte de um domínio, se um servidor DNS está acessível ou se a rede está conectada. Provavelmente não entendi sua explicação, mas o resultado é o que eu esperava. (Máquina: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO hostname: TESTNAME-VERYLONG)
marsh-wiggle de
Por que você usa Dns.GetHostName()para em hostNamevez de usar a HostNamepropriedade do IPGlobalPropertiesobjeto que você já possui, uma linha acima?
Xharlie
@Xharlie porque a IPGlobalPropertiespropriedade hostname retorna o nome NetBIOS, enquanto Dns.GetHostName()retorna o nome do host DNS.
Mike Dinescu
2
a EndsWithverificação é quebrada para nomes de host que terminam com as mesmas letras do nome de domínio (por exemplo, um host MYHOST no domínio OST), provavelmente deveria serEndsWith("." + domainName)
user3391859
6
Se domainName estiver vazio, isso retornará hostName.. Deve haver uma !String.isNullorEmpty(domainName)verificação
RodgerTheGreat
63

Uma ligeira simplificação do código de Miky D

    public static string GetLocalhostFqdn()
    {
        var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
        return string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
    }
Matt Z
fonte
4
Ao contrário do código de Micky D, ele retorna o nome do host com uma parada completa anexada se a máquina não for membro de um domínio.
Bosco
1
Além disso, usa o nome NetBIOS em vez do nome do host DNS. Acredito que os nomes NetBIOS são adequados apenas em LANs.
Sam
Talvez adicione um .Trim(".")à última linha para se livrar do. se existe.
David d C e Freitas
28

Isso é coberto por este artigo . Essa técnica é mais breve do que a resposta aceita e provavelmente mais confiável do que a próxima resposta mais votada. Observe que, tanto quanto eu entendo, isso não usa nomes NetBIOS, então deve ser adequado para uso na Internet.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName
Sam
fonte
@DexterLegaspi - A resposta de Sam é boa (até eu mesma a avaliei), mas não é equivalente à minha resposta, nem necessariamente melhor. Por favor, veja minha resposta atualizada para detalhes.
Mike Dinescu
@MikeDinescu a questão é como obter o FQDN, o que denota que a máquina está em uma rede e parte de um domínio. a resposta aceita faz o trabalho, mas a resposta de Sam é mais "precisa" (por falta de um termo melhor)
Dexter Legaspi
3
Essa é a resposta correta! mas em vez de fazê- Dns.GetHostEntry("LocalHost").HostNamelo é melhor passar uma string vazia como:Dns.GetHostEntry("").HostName
paulgutten
17

Aqui está no PowerShell, para falar a verdade:

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

E para o Framework 1.1 é tão simples quanto isto:

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

Em seguida, remova o nome NETBIOS da máquina para recuperar apenas o nome do domínio

Javizcaino
fonte
Aqui em 2013, GetHostByName("localhost")está obsoleto. O VS 2010 sugeriu que eu usasse GetHostEntry("localhost"), o que funciona bem.
piedar
@piedar, você deve ter esquecido um pouco sobre isso ser para .NET 1.1.
Sam
Eu queria adicionar informações atualizadas a esta resposta, pois era a mais simples e, portanto, minha favorita. Provavelmente não rolei longe o suficiente para ver sua resposta, o que de fato tornou meu comentário desnecessário.
piedar
8

Você pode tentar o seguinte:

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

Este shoud fornece o FQDN da máquina local atual (ou você pode especificar qualquer host).

UT-Fan-05
fonte
5

Uma ligeira melhoria na resposta de Matt Z para que um ponto final final não seja retornado se o computador não for membro de um domínio:

public static string GetLocalhostFqdn()
{
    var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    return string.IsNullOrWhiteSpace(ipProperties.DomainName) ? ipProperties.HostName : string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
}
Bosco
fonte
Observe que eu acho que ele usa o nome do host NetBIOS, portanto, pode não ser adequado para uso na Internet.
Sam
2

Usei isso como uma das minhas opções para combinar o nome do host e o nome do domínio para construir um relatório, adicionei o texto genérico para preencher quando o nome do domínio não fosse capturado, este era um dos requisitos do cliente.

Eu testei isso usando 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
} 

Construído usando as idéias da solução Miky Dinescu.

user3500031
fonte
1

Implementamos o resultado sugerido para usar desta forma:

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

No entanto, descobriu-se que isso não funciona direito quando o nome do computador tem mais de 15 caracteres e usa o nome NetBios. O Environment.MachineName retorna apenas o nome parcial e o nome do host de resolução retorna o mesmo nome de computador.

Depois de alguma pesquisa, encontramos uma solução para corrigir esse problema:

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

Isso resolveu todos os problemas, incluindo o nome do computador.

btomas
fonte
Isso lançará uma exceção, e a maioria das outras soluções sugeridas também falharão, se você tiver um computador que recebeu um nome do usuário contendo caracteres que não sejam az, 0-9, '.', '-'. Portanto, espere problemas se tiver usuários na Ásia ou semelhantes. GetHostName terá esses caracteres substituídos por '?'. É por isso que prefiro GetHostByName ("localhost"). HostName, que mostra o nome real do computador.
Göran,
0

Eu usei esta abordagem:

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

Nenhuma das respostas fornecidas que eu testei realmente forneceu o sufixo DNS que eu estava procurando. Aqui está o que eu inventei.

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

Se você quiser organizá-lo e lidar com exceções, tente o seguinte:

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;
        }
Roger Willcocks
fonte
2
"e lidar com exceções" - FALHA.
Jörgen Sigvardsson
vc acha que pegar sozinho lida com a exceção!
Saher Ahwal
Não, acho que como você deseja lidar com as exceções é algo que você precisa decidir por si mesmo. E se você não puder obter um nome de domínio de volta, como VOCÊ se propõe a lidar com isso?
Roger Willcocks
4
Registre um relatório de erro e avise o usuário de que algo deu errado em vez de fornecer informações incorretas ao código do cliente.
dahvyd