Як знайти повне доменне ім’я локальної машини в C # / .NET?


87

Як ви можете отримати повне доменне ім’я локальної машини в C #?

Відповіді:


143

ПРИМІТКА. Це рішення працює лише при націлюванні на .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
}

ОНОВЛЕННЯ

Оскільки багато людей коментують, що відповідь Сема є більш стислою, я вирішив додати кілька відповідей до відповіді.

Найголовніше, що слід зазначити, це те, що код, який я дав, не еквівалентний наступному коду:

Dns.GetHostEntry("LocalHost").HostName

Хоча в загальному випадку, коли машина підключена до мережі та є частиною домену, обидва методи, як правило, дають однаковий результат, в інших сценаріях результати будуть відрізнятися.

Сценарій, коли вихід буде іншим, - це коли машина не є частиною домену. У цьому випадку функція Dns.GetHostEntry("LocalHost").HostNameповернеться, localhostтоді як GetFQDN()метод вище поверне ім'я NETBIOS хосту.

Ця відмінність важлива, коли метою пошуку повного доменного імені машини є реєстрація інформації або створення звіту. Більшу частину часу я використовував цей метод у журналах або звітах, які згодом використовувались для відображення інформації назад до певної машини. Якщо машини не з'єднані в мережу, localhostідентифікатор марний, тоді як ім'я дає необхідну інформацію.

Тож, зрештою, від кожного користувача залежить, який метод найкраще підходить для їх застосування, залежно від того, який результат їм потрібен. Але сказати, що ця відповідь неправильна, оскільки недостатньо стисла, - це в кращому випадку поверхнево.

Дивіться приклад, коли вихідні дані будуть різними: http://ideone.com/q4S4I0


2
За допомогою Dns.GetHostEntry("LocalHost").HostNameя завжди отримую ім'я хосту (не netbios) із суфіксом основного домену. Це не залежить від того, чи є машина частиною домену, чи доступний DNS-сервер, чи підключена мережа. Можливо, я не розумію вашого пояснення, але результат я очікую. (Машина: W2008R2; .net 4.0; ім'я netbios: TESTNAME-VERYLO ім'я хосту: TESTNAME-VERYLONG)
-wiggle

Чому ви використовуєте Dns.GetHostName()для hostNameзамість того щоб використовувати HostNameвластивість IPGlobalPropertiesоб'єкта у вас вже є, один рядок вище?
Шарлі

@Xharlie, оскільки IPGlobalPropertiesвластивість ім'я хосту повертає ім'я NetBIOS, тоді як Dns.GetHostName()повертає ім'я хосту DNS.
Mike Dinescu

2
EndsWithчек зламана для імен хостів , які закінчуються з тими ж буквами, що доменне ім'я (наприклад, хост MyHost в домені ОСТ), слід , ймовірно,EndsWith("." + domainName)
user3391859

6
Якщо domainName порожнє, це повертається hostName.. Повинна бути !String.isNullorEmpty(domainName)перевірка
RodgerTheGreat

63

Невелике спрощення коду Мікі Д.

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

4
На відміну від коду Мікі D, це повертає ім'я хосту з доданою точкою, якщо машина не є членом домену.
Боско

1
Крім того, тут використовується ім'я NetBIOS замість імені хосту DNS. Я вважаю, що імена NetBIOS підходять лише для локальних мереж.
Сем

Можливо, .Trim(".")до останнього рядка додайте a, щоб позбутися. якщо вона існує.
David d C e Freitas,

28

Це висвітлено в цій статті . Цей прийом є коротшим, ніж прийнята відповідь, і, мабуть, надійнішим, ніж наступна відповідь з найбільшим голосом. Зауважте, що, наскільки я розумію, тут не використовуються імена NetBIOS, тому він повинен бути придатним для використання в Інтернеті.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName

@DexterLegaspi - відповідь Сема хороша (я навіть сам її підготував), але це не рівнозначно моїй відповіді і не обов'язково краще. Детальніше див. Мою оновлену відповідь.
Mike Dinescu

@MikeDinescu питання полягає в тому, як отримати повне доменне ім'я, яке означає, що машина знаходиться в мережі та є частиною домену. прийнята відповідь робить свою справу, але відповідь Сема є більш "точною" (за відсутності кращого терміну)
Декстер Легаспі,

3
це правильна відповідь! але замість того, щоб робити це, Dns.GetHostEntry("LocalHost").HostNameвам краще передати порожній рядок так:Dns.GetHostEntry("").HostName
paulgutten

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, щоб отримати лише ім'я домену


Тут у 2013 році GetHostByName("localhost")застарілий. VS 2010 запропонував використовувати GetHostEntry("localhost")замість цього, що чудово працює.
piedar

@piedar, можливо, ти пропустив трохи про те, що стосується .NET 1.1.
Сем

Я хотів додати оновлену інформацію до цієї відповіді, оскільки вона була найпростішою і, отже, моєю улюбленою. Можливо, я прокрутив недостатньо далеко, щоб побачити вашу відповідь, що справді зробило мій коментар непотрібним.
piedar

8

Ви можете спробувати наступне:

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

Це має надати вам повне доменне ім’я поточної локальної машини (або ви можете вказати будь-якого хоста).


5

Невелике покращення відповіді Метта 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, тому воно може бути непридатним для використання в Інтернеті.
Сем

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
} 

Побудований за ідеями рішення Мікі Дінеску.


1

Ми застосували запропонований результат, щоб використовувати такий спосіб:

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

Однак виявилося, що це не працює правильно, якщо ім'я комп'ютера довше 15 символів і використовується ім'я NetBios. Environment.MachineName повертає лише часткове ім'я, а вирішення імені хосту - те саме ім'я комп'ютера.

Після деяких досліджень ми знайшли вирішення цієї проблеми:

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

Це вирішило всі проблеми, включаючи ім’я комп’ютера.


Це призведе до винятку, і більшість інших запропонованих рішень також не вдасться, якщо у вас є комп’ютер, якому користувач дав ім’я, що містить символи, не від az, 0-9, „. Тож очікуйте проблем, якщо у вас є користувачі в Азії чи подібних. У GetHostName ці символи будуть замінені на '?'. Ось чому я віддаю перевагу GetHostByName ("localhost"). HostName, яке відображає фактичне ім'я комп'ютера.
Геран

0

Я використав такий підхід:

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

0

Жодна з відповідей, передбачених моїм тестуванням, насправді не містила шуканий суфікс DNS. Ось що я придумав.

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

-9

Якщо ви хочете привести його в порядок і обробити винятки, спробуйте наступне:

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
"та обробляти винятки" - FAIL.
Йорген Зігвардссон,

ти думаєш, що сам улов справляється з винятком!
Saher Ahwal

Ні, я думаю, що як ви хочете обробляти винятки - це те, що вам потрібно вирішити самостійно. І якщо ви не можете повернути доменне ім’я, як би ви пропонували з ним справитись?
Роджер Вілкокс

4
Запишіть звіт про помилку та попередьте користувача, що щось пішло не так, замість того, щоб надавати коду клієнта дефектну інформацію.
dahvyd
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.