Come trovare FQDN della macchina locale in C # /. NET?


89

Come puoi ottenere l'FQDN di una macchina locale in C #?

Risposte:


143

NOTA: questa soluzione funziona solo quando si utilizza come destinazione i framework .NET 2.0 (e più recenti).

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
}

AGGIORNARE

Poiché molte persone hanno commentato che la risposta di Sam è più concisa, ho deciso di aggiungere alcuni commenti alla risposta.

La cosa più importante da notare è che il codice che ho fornito non è equivalente al codice seguente:

Dns.GetHostEntry("LocalHost").HostName

Mentre nel caso generale in cui la macchina è collegata in rete e fa parte di un dominio, entrambi i metodi generalmente producono lo stesso risultato, in altri scenari i risultati saranno diversi.

Uno scenario in cui l'output sarà diverso è quando la macchina non fa parte di un dominio. In questo caso, Dns.GetHostEntry("LocalHost").HostNameverrà restituito localhostmentre il GetFQDN()metodo precedente restituirà il nome NETBIOS dell'host.

Questa distinzione è importante quando lo scopo della ricerca del nome di dominio completo della macchina è registrare le informazioni o generare un report. La maggior parte delle volte ho utilizzato questo metodo nei registri o nei rapporti che vengono successivamente utilizzati per mappare le informazioni su una macchina specifica. Se le macchine non sono collegate in rete, l' localhostidentificatore è inutile, mentre il nome fornisce le informazioni necessarie.

Quindi, in definitiva, spetta a ciascun utente quale metodo è più adatto alla propria applicazione, a seconda del risultato di cui ha bisogno. Ma dire che questa risposta è sbagliata per non essere abbastanza concisa è nella migliore delle ipotesi superficiale.

Guarda un esempio in cui l'output sarà diverso: http://ideone.com/q4S4I0


2
Usando Dns.GetHostEntry("LocalHost").HostNameottengo sempre il nome host (non netbios) con il suffisso del dominio primario. Ciò non dipende dal fatto che la macchina faccia parte di un dominio, che un server DNS sia raggiungibile o che il netzwork sia connesso. Probabilmente non capisco la tua spiegazione ma il risultato è quello che mi aspetto. (Macchina: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO hostname: TESTNAME-VERYLONG)
marsh-wiggle

Perché usi Dns.GetHostName()per hostNameinvece di usare la HostNameproprietà IPGlobalPropertiesdell'oggetto che hai già, una riga sopra?
Xharlie

@Xharlie perché la IPGlobalPropertiesproprietà hostname restituisce il nome NetBIOS, mentre Dns.GetHostName()restituisce il nome host DNS.
Mike Dinescu

2
il EndsWithcontrollo è interrotto per i nomi host che terminano con le stesse lettere del nome di dominio (ad esempio un host MYHOST nel dominio OST), dovrebbe probabilmente essereEndsWith("." + domainName)
user3391859

7
Se domainName è vuoto, viene restituito hostName.. Dovrebbe esserci un !String.isNullorEmpty(domainName)assegno
RodgerTheGreat

63

Una leggera semplificazione del codice di Miky D.

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

4
A differenza del codice di Micky D, questo restituisce il nome host con un fullstop aggiunto se la macchina non è un membro di un dominio.
Bosco

1
Inoltre, utilizza il nome NetBIOS invece del nome host DNS. Credo che i nomi NetBIOS siano adatti solo all'interno delle LAN.
Sam

Forse aggiungi una .Trim(".")all'ultima riga per eliminare il file. se esiste.
David d C e Freitas

29

Questo è trattato in questo articolo . Questa tecnica è più breve della risposta accettata e probabilmente più affidabile della successiva risposta più votata. Nota che per quanto ho capito, questo non usa nomi NetBIOS, quindi dovrebbe essere adatto per l'uso di Internet.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName

@DexterLegaspi - La risposta di Sam è buona (l'ho persino migliorata io stesso) ma non è equivalente alla mia risposta, né necessariamente migliore. Si prega di consultare la mia risposta aggiornata per i dettagli.
Mike Dinescu

@ MikeDinescu la domanda è come ottenere FQDN, che connota che la macchina si trova su una rete e fa parte di un dominio. la risposta accettata fa il suo lavoro ma la risposta di Sam è più "precisa" (per mancanza di un termine migliore)
Dexter Legaspi

4
questa è la risposta corretta! ma invece di farlo Dns.GetHostEntry("LocalHost").HostNameè meglio che passi una stringa vuota in questo modo:Dns.GetHostEntry("").HostName
paulgutten

17

Eccolo in PowerShell, per il gusto di farlo:

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

15

E per Framework 1.1 è così semplice:

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

Quindi rimuovere il nome NETBIOS della macchina per recuperare solo il domainName


Qui nel 2013 GetHostByName("localhost")è obsoleto. VS 2010 mi ha suggerito di usare GetHostEntry("localhost")invece, che funziona bene.
piedar

@piedar, potresti aver perso la parte di questo per .NET 1.1.
Sam

Volevo aggiungere informazioni aggiornate a questa risposta, poiché era la più semplice e quindi la mia preferita. Probabilmente non ho fatto scorrere abbastanza lontano per vedere la tua risposta, il che aveva effettivamente reso il mio commento non necessario.
piedar

8

Puoi provare quanto segue:

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

Questo dovrebbe darti l'FQDN della macchina locale corrente (oppure puoi specificare qualsiasi host).


5

Un leggero miglioramento sulla risposta di Matt Z in modo che un punto finale non venga restituito se il computer non è un membro di un dominio:

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

Nota che penso che questo utilizzi il nome host NetBIOS, quindi potrebbe non essere adatto per l'uso di Internet.
Sam

2

Ho usato questa come una delle mie opzioni per combinare il nome host e il nome di dominio per la creazione di un report, ho aggiunto il testo generico da compilare quando il nome di dominio non è stato acquisito, questo era uno dei requisiti del cliente.

L'ho testato utilizzando 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
} 

Costruito utilizzando idee dalla soluzione Miky Dinescu.


1

Abbiamo implementato il risultato suggerito da utilizzare in questo modo:

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

Tuttavia, si è scoperto che questo non funziona correttamente quando il nome del computer è più lungo di 15 caratteri e utilizza il nome NetBios. Environment.MachineName restituisce solo un nome parziale e la risoluzione del nome host restituisce lo stesso nome del computer.

Dopo alcune ricerche abbiamo trovato una soluzione per risolvere questo problema:

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

Ciò ha risolto tutti i problemi, incluso il nome del computer.


Ciò genererà un'eccezione e anche la maggior parte delle altre soluzioni suggerite fallirà, se si dispone di un computer a cui è stato assegnato un nome dall'utente contenente caratteri diversi da az, 0-9, '.', '-'. Quindi aspettati problemi se hai utenti in Asia o simili. GetHostName avrà quei caratteri sostituiti da "?". Ecco perché preferisco GetHostByName ("localhost"). HostName che mostra il nome effettivo del computer.
Göran

0

Ho usato questo approccio:

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

0

Nessuna delle risposte fornite che ho testato ha effettivamente fornito il suffisso DNS che stavo cercando. Ecco cosa mi è venuto in mente.

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

0

La mia raccolta di metodi per gestire tutti i casi relativi a 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;
    }

-9

Se vuoi rimetterlo in ordine e gestire le eccezioni, prova questo:

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

2
"e gestire le eccezioni" - FAIL.
Jörgen Sigvardsson

pensi che la cattura da sola gestisca l'eccezione!
Saher Ahwal

No, penso che il modo in cui vuoi gestire le eccezioni sia qualcosa che devi decidere da solo. E se non riesci a recuperare un nome di dominio, come proporresti di gestirlo?
Roger Willcocks

4
Registra un rapporto di errore e avvisa l'utente che qualcosa è andato storto invece di fornire al codice client informazioni errate.
dahvyd
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.