Как найти полное доменное имя локальной машины в 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 хоста.

Это различие важно, когда целью поиска FQDN машины является регистрация информации или создание отчета. Большую часть времени я использовал этот метод в журналах или отчетах, которые впоследствии использовались для сопоставления информации с конкретной машиной. Если машины не подключены к сети, localhostидентификатор бесполезен, тогда как имя дает необходимую информацию.

Таким образом, в конечном итоге каждый пользователь должен решать, какой метод лучше подходит для его приложения, в зависимости от того, какой результат им нужен. Но сказать, что этот ответ неверен из-за того, что он недостаточно краток, в лучшем случае поверхностно.

См. Пример, в котором результат будет другим: http://ideone.com/q4S4I0


2
При использовании Dns.GetHostEntry("LocalHost").HostNameя всегда получаю имя хоста (не netbios) с суффиксом основного домена. Это не зависит от того, является ли машина частью домена, доступен DNS-сервер или подключена сеть. Возможно, я не понимаю вашего объяснения, но результат такой, как я ожидал. (Машина: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO hostname: TESTNAME-VERYLONG)
marsh-wiggle

Почему вы используете Dns.GetHostName()for hostNameвместо использования HostNameсвойства IPGlobalPropertiesобъекта, который у вас уже есть, на одну строку выше?
Xharlie

@Xharlie, потому что IPGlobalPropertiesсвойство hostname возвращает имя NetBIOS, тогда как Dns.GetHostName()возвращает имя хоста DNS.
Майк Динеску

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

6
Если domainName пусто, возвращается hostName.. Должен быть !String.isNullorEmpty(domainName)чек
RodgerTheGreat

63

Небольшое упрощение кода Miky D

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

4
В отличие от кода Micky D, он возвращает имя хоста с добавленной точкой полной остановки, если машина не является членом домена.
Bosco

1
Кроме того, здесь используется имя NetBIOS вместо имени хоста DNS. Я считаю, что имена NetBIOS подходят только в локальных сетях.
Сэм

Возможно, добавьте .Trim(".")в последнюю строку, чтобы избавиться от. если он существует.
David d C e Freitas

28

Это рассматривается в этой статье . Этот метод короче принятого ответа и, вероятно, более надежен, чем следующий ответ, получивший наибольшее количество голосов. Обратите внимание, что, насколько я понимаю, здесь не используются имена NetBIOS, поэтому он должен подходить для использования в Интернете.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0–1.1

Dns.GetHostByName("LocalHost").HostName

@DexterLegaspi - ответ Сэма хороший (я даже сам его повысил), но он не эквивалентен моему ответу и не обязательно лучше. См. Подробности в моем обновленном ответе.
Майк Динеску

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

3
Это правильный ответ! но вместо этого Dns.GetHostEntry("LocalHost").HostNameвам лучше передать пустую строку вот так:Dns.GetHostEntry("").HostName
paulgutten 08

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 08

@piedar, вы могли упустить момент о том, что это для .NET 1.1.
Сэм

Я хотел добавить обновленную информацию к этому ответу, так как он был самым простым и, следовательно, моим любимым. Я, вероятно, не прокрутил достаточно далеко, чтобы увидеть ваш ответ, который действительно сделал мой комментарий ненужным.
piedar

8

Вы можете попробовать следующее:

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

Это shoud предоставит вам полное доменное имя текущего локального компьютера (или вы можете указать любой хост).


5

Небольшое улучшение ответа Мэтта Зи, так что конечная точка не возвращается, если компьютер не является членом домена:

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

Обратите внимание: я думаю, что здесь используется имя хоста NetBIOS, поэтому оно может не подходить для использования в Интернете.
Sam

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
«и обрабатывать исключения» - НЕИСПРАВНОСТЬ.
Jörgen Sigvardsson

Вы думаете, что catch сам по себе обрабатывает исключение!
Saher Ahwal 05

Нет, я думаю, что вам нужно решить, как вы хотите обрабатывать исключения. И если вы не можете вернуть доменное имя, как вы предлагаете с этим справиться?
Роджер Уиллкокс

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