Jak znaleźć FQDN komputera lokalnego w C # / .NET?

87

Jak uzyskać nazwę FQDN komputera lokalnego w języku C #?

Sam
źródło

Odpowiedzi:

143

UWAGA: To rozwiązanie działa tylko w przypadku platformy .NET 2.0 (i nowszej).

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
}

AKTUALIZACJA

Ponieważ wiele osób skomentowało, że odpowiedź Sama jest bardziej zwięzła, postanowiłem dodać kilka komentarzy do odpowiedzi.

Najważniejszą rzeczą do zapamiętania jest to, że kod, który podałem, nie jest równoważny z następującym kodem:

Dns.GetHostEntry("LocalHost").HostName

Podczas gdy w ogólnym przypadku, gdy maszyna jest podłączona do sieci i stanowi część domeny, obie metody generalnie dadzą ten sam wynik, w innych scenariuszach wyniki będą się różnić.

Scenariusz, w którym dane wyjściowe będą inne, to sytuacja, w której maszyna nie jest częścią domeny. W tym przypadku Dns.GetHostEntry("LocalHost").HostNamezwróci wartość, localhosta GetFQDN()powyższa metoda zwróci nazwę NETBIOS hosta.

To rozróżnienie jest ważne, gdy celem znalezienia nazwy FQDN maszyny jest zarejestrowanie informacji lub wygenerowanie raportu. Przez większość czasu korzystałem z tej metody w dziennikach lub raportach, które są następnie używane do mapowania informacji z powrotem do określonej maszyny. Jeśli maszyny nie są podłączone do sieci, localhostidentyfikator jest bezużyteczny, podczas gdy nazwa zawiera potrzebne informacje.

Ostatecznie to od każdego użytkownika zależy, która metoda będzie lepiej dopasowana do jego aplikacji, w zależności od tego, jakiego wyniku potrzebują. Ale stwierdzenie, że ta odpowiedź jest błędna, ponieważ nie jest wystarczająco zwięzła, jest w najlepszym przypadku powierzchowne.

Zobacz przykład, w którym wynik będzie inny: http://ideone.com/q4S4I0

Mike Dinescu
źródło
2
Używając Dns.GetHostEntry("LocalHost").HostName, zawsze otrzymuję nazwę hosta (nie netbios) z sufiksem domeny podstawowej. Nie zależy to od tego, czy maszyna jest częścią domeny, czy serwer DNS jest osiągalny, czy sieć jest podłączona. Prawdopodobnie nie rozumiem twojego wyjaśnienia, ale wynik jest taki, jakiego oczekuję. (Maszyna: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO nazwa hosta: TESTNAME-VERYLONG)
marsh-wiggle
Dlaczego używasz Dns.GetHostName()for hostNamezamiast używać HostNamewłaściwości IPGlobalPropertiesobiektu, który już masz, jeden wiersz powyżej?
Xharlie
@Xharlie, ponieważ IPGlobalPropertieswłaściwość hostname zwraca nazwę NetBIOS, podczas gdy Dns.GetHostName()zwraca nazwę hosta DNS.
Mike Dinescu
2
EndsWithwyboru jest złamane dla hostów, że koniec z tymi samymi literami jak nazwy domeny (np myhost gospodarza w OST domeny), powinny prawdopodobnieEndsWith("." + domainName)
user3391859
6
Jeśli nazwa_domeny jest pusta, to zwraca hostName.. Powinien być !String.isNullorEmpty(domainName)czek
RodgerTheGreat
63

Drobne uproszczenie kodu Miky D.

    public static string GetLocalhostFqdn()
    {
        var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
        return string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
    }
Matt Z
źródło
4
W przeciwieństwie do kodu Micky D zwraca to nazwę hosta z dołączoną kropką, jeśli maszyna nie jest członkiem domeny.
Bosco
1
Ponadto używa nazwy NetBIOS zamiast nazwy hosta DNS. Uważam, że nazwy NetBIOS są odpowiednie tylko w sieciach LAN.
Sam
Być może dodaj a .Trim(".")do ostatniej linii, aby pozbyć się. jeśli istnieje.
David d C e Freitas
28

Jest to omówione w tym artykule . Ta technika jest krótsza niż zaakceptowana odpowiedź i prawdopodobnie bardziej wiarygodna niż kolejna odpowiedź z największą liczbą głosów. Zauważ, że o ile rozumiem, nie używa to nazw NetBIOS, więc powinno być odpowiednie do użytku w Internecie.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName
Sam
źródło
@DexterLegaspi - odpowiedź Sama jest dobra (nawet sam ją zaktualizowałem), ale nie jest to odpowiednik mojej odpowiedzi ani niekoniecznie lepsza. Zobacz moją zaktualizowaną odpowiedź, aby uzyskać szczegółowe informacje.
Mike Dinescu
@MikeDinescu pytanie brzmi, jak uzyskać FQDN, co oznacza, że ​​maszyna jest w sieci i jest częścią domeny. zaakceptowana odpowiedź spełnia swoje zadanie, ale odpowiedź Sama jest bardziej „precyzyjna” (z braku lepszego określenia)
Dexter Legaspi
3
to jest poprawna odpowiedź! ale zamiast robić Dns.GetHostEntry("LocalHost").HostName, lepiej Dns.GetHostEntry("").HostName
podaj
17

Tutaj jest w PowerShell, do cholery:

$ipProperties = [System.Net.NetworkInformation.IPGlobalProperties]::GetIPGlobalProperties()
"{0}.{1}" -f $ipProperties.HostName, $ipProperties.DomainName
halr9000
źródło
15

A dla Framework 1.1 jest tak proste:

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

Następnie usuń nazwę NETBIOS komputera, aby pobrać tylko nazwę domeny

javizcaino
źródło
Tutaj w 2013 roku GetHostByName("localhost")jest przestarzały. VS 2010 zasugerował, żebym GetHostEntry("localhost")zamiast tego użył , co działa dobrze.
piedar
@piedar, być może przegapiłeś trochę o tym, że chodzi o .NET 1.1.
Sam,
Chciałem dodać aktualne informacje do tej odpowiedzi, ponieważ była to najprostsza i przez to moja ulubiona. Prawdopodobnie nie przewinąłem wystarczająco daleko, aby zobaczyć twoją odpowiedź, co rzeczywiście sprawiło, że mój komentarz stał się niepotrzebny.
piedar
8

Możesz spróbować następujących rzeczy:

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

Powinno to podać nazwę FQDN bieżącej maszyny lokalnej (lub możesz określić dowolnego hosta).

UT-Fan-05
źródło
5

Niewielkie ulepszenie odpowiedzi Matta Z, tak że kropka na końcu nie jest zwracana, jeśli komputer nie jest członkiem domeny:

public static string GetLocalhostFqdn()
{
    var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    return string.IsNullOrWhiteSpace(ipProperties.DomainName) ? ipProperties.HostName : string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
}
Bosco
źródło
Zauważ, że myślę, że używa nazwy hosta NetBIOS, więc może nie nadawać się do użytku w Internecie.
Sam
2

Użyłem tego jako jednej z moich opcji połączenia nazwy hosta i nazwy domeny w celu zbudowania raportu, dodałem ogólny tekst do wypełnienia, gdy nazwa domeny nie została przechwycona, było to jedno z wymagań klientów.

Przetestowałem to przy użyciu 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
} 

Zbudowany przy użyciu pomysłów z rozwiązania Miky Dinescu.

user3500031
źródło
1

Zaimplementowaliśmy sugerowany wynik do wykorzystania w ten sposób:

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

Okazało się jednak, że nie działa to dobrze, gdy nazwa komputera jest dłuższa niż 15 znaków i używa nazwy NetBios. Środowisko Environment.MachineName zwraca tylko częściową nazwę, a rozpoznawanie nazwy hosta zwraca tę samą nazwę komputera.

Po kilku badaniach znaleźliśmy rozwiązanie tego problemu:

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

To rozwiązało wszystkie problemy, w tym nazwę komputera.

btomas
źródło
Spowoduje to zgłoszenie wyjątku, a większość innych sugerowanych rozwiązań również zakończy się niepowodzeniem, jeśli masz komputer, któremu użytkownik nadał nazwę zawierającą znaki inne niż az, 0-9, „.”, „-”. Spodziewaj się więc problemów, jeśli masz użytkowników w Azji lub podobnych. GetHostName zastąpi te znaki znakiem „?”. Dlatego wolę GetHostByName („localhost”). HostName, który pokazuje rzeczywistą nazwę komputera.
Göran
0

Użyłem tego podejścia:

private static string GetLocalhostFQDN()
{
    var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    return $"{ipProperties.HostName}.{ipProperties.DomainName}";
}
isxaker
źródło
0

Żadna z odpowiedzi, które testowałem, nie zawierała sufiksu DNS, którego szukałem. Oto, co wymyśliłem.

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

Jeśli chcesz to uporządkować i obsłużyć wyjątki, spróbuj tego:

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
źródło
2
„i obsłuż wyjątki” - FAIL.
Jörgen Sigvardsson
myślisz, że sam złapanie obsługuje wyjątek!
Saher Ahwal,
Nie, myślę, że to, w jaki sposób chcesz obsługiwać wyjątki, musisz samodzielnie zdecydować. A jeśli nie możesz odzyskać nazwy domeny, w jaki sposób TY możesz sobie z tym poradzić?
Roger Willcocks
4
Zarejestruj raport o błędzie i ostrzeż użytkownika, że ​​coś poszło nie tak, zamiast dostarczać do kodu klienta błędne informacje.
dahvyd