Comment trouver le nom de domaine complet de la machine locale dans C # /. NET?

87

Comment pouvez-vous obtenir le nom de domaine complet d'une machine locale en C #?

Sam
la source

Réponses:

142

REMARQUE: cette solution fonctionne uniquement lorsque vous ciblez les frameworks .NET 2.0 (et plus récents).

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
}

METTRE À JOUR

Comme beaucoup de gens ont dit que la réponse de Sam était plus concise, j'ai décidé d'ajouter quelques commentaires à la réponse.

La chose la plus importante à noter est que le code que j'ai donné n'est pas équivalent au code suivant:

Dns.GetHostEntry("LocalHost").HostName

Alors que dans le cas général où la machine est en réseau et fait partie d'un domaine, les deux méthodes produiront généralement le même résultat, dans d'autres scénarios, les résultats seront différents.

Un scénario où la sortie sera différente est lorsque la machine ne fait pas partie d'un domaine. Dans ce cas, leDns.GetHostEntry("LocalHost").HostName retournera localhosttandis que la GetFQDN()méthode ci-dessus renverra le nom NETBIOS de l'hôte.

Cette distinction est importante lorsque le but de la recherche du nom de domaine complet de la machine est de consigner des informations ou de générer un rapport. La plupart du temps, j'ai utilisé cette méthode dans des journaux ou des rapports qui sont ensuite utilisés pour mapper des informations à une machine spécifique. Si les machines ne sont pas en réseau, l' localhostidentifiant est inutile, alors que le nom donne les informations nécessaires.

C'est donc finalement à chaque utilisateur quelle méthode est la mieux adaptée à son application, en fonction du résultat dont il a besoin. Mais dire que cette réponse est erronée parce qu'elle n'est pas assez concise est au mieux superficiel.

Voir un exemple où la sortie sera différente: http://ideone.com/q4S4I0

Mike Dinescu
la source
2
En utilisant, Dns.GetHostEntry("LocalHost").HostNamej'obtiens toujours le nom d'hôte (pas netbios) avec le suffixe de domaine principal. Cela ne dépend pas si la machine fait partie d'un domaine, si un serveur DNS est accessible ou si le réseau est connecté. Je ne comprends probablement pas votre explication, mais le résultat est ce que j'attends. (Machine: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO hostname: TESTNAME-VERYLONG)
marsh-wiggle
Pourquoi utilisez-vous Dns.GetHostName()pour hostNameau lieu d'utiliser la HostNamepropriété de l' IPGlobalPropertiesobjet que vous avez déjà, une ligne au-dessus?
Xharlie
@Xharlie car la IPGlobalPropertiespropriété hostname renvoie le nom NetBIOS, alors que Dns.GetHostName()renvoie le nom d'hôte DNS.
Mike Dinescu
2
le EndsWithchèque est cassé pour les noms d'hôte qui se terminent par les mêmes lettres que le nom de domaine (par exemple un hôte MYHOST dans le domaine OST), devrait probablement êtreEndsWith("." + domainName)
user3391859
6
Si domainName est vide, cela revient hostName.. Il devrait y avoir un !String.isNullorEmpty(domainName)chèque
RodgerTheGreat
63

Une légère simplification du code de Miky D

    public static string GetLocalhostFqdn()
    {
        var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
        return string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
    }
Matt Z
la source
4
Contrairement au code de Micky D, cela renvoie le nom d'hôte avec un point final ajouté si la machine n'est pas membre d'un domaine.
Bosco
1
En outre, cela utilise le nom NetBIOS au lieu du nom d'hôte DNS. Je pense que les noms NetBIOS ne conviennent que dans les réseaux locaux.
Sam
Ajoutez peut-être un .Trim(".")à la dernière ligne pour supprimer le fichier. s'il existe.
David d C e Freitas
28

Ceci est couvert par cet article . Cette technique est plus brève que la réponse acceptée et probablement plus fiable que la prochaine réponse la plus votée. Notez que pour autant que je sache, cela n'utilise pas de noms NetBIOS, il devrait donc convenir à une utilisation Internet.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName
Sam
la source
@DexterLegaspi - La réponse de Sam est bonne (je l'ai même mise à jour moi-même) mais elle n'est pas équivalente à ma réponse, ni nécessairement meilleure. Veuillez consulter ma réponse mise à jour pour plus de détails.
Mike Dinescu
@MikeDinescu, la question est de savoir comment obtenir le FQDN, ce qui signifie que la machine est sur un réseau et fait partie d'un domaine. la réponse acceptée fait le travail mais la réponse de Sam est plus "précise" (faute d'un meilleur terme)
Dexter Legaspi
3
c'est la bonne réponse! mais au lieu de Dns.GetHostEntry("LocalHost").HostNamevous faire mieux passer une chaîne vide comme ceci:Dns.GetHostEntry("").HostName
paulgutten
17

Le voici dans PowerShell, pour le plaisir:

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

Et pour Framework 1.1, c'est aussi simple que ceci:

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

Et puis supprimez le nom NETBIOS de la machine pour récupérer uniquement le nom de domaine

Javizcaino
la source
Ici en 2013, GetHostByName("localhost")est obsolète. VS 2010 m'a suggéré d'utiliser à la GetHostEntry("localhost")place, ce qui fonctionne très bien.
piedar
@piedar, vous avez peut-être manqué le peu à propos de .NET 1.1.
Sam
Je voulais ajouter des informations mises à jour à cette réponse, car c'était la plus simple et donc ma préférée. Je n'ai probablement pas fait défiler assez loin pour voir votre réponse, ce qui avait en effet rendu mon commentaire inutile.
piedar
8

Vous pouvez essayer ce qui suit:

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

Cela devrait vous donner le FQDN de la machine locale actuelle (ou vous pouvez spécifier n'importe quel hôte).

UT-Fan-05
la source
5

Une légère amélioration par rapport à la réponse de Matt Z pour qu'un point final ne soit pas renvoyé si l'ordinateur n'est pas membre d'un domaine:

public static string GetLocalhostFqdn()
{
    var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
    return string.IsNullOrWhiteSpace(ipProperties.DomainName) ? ipProperties.HostName : string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
}
Bosco
la source
Notez que je pense que cela utilise le nom d'hôte NetBIOS, il peut donc ne pas convenir à une utilisation Internet.
Sam
2

Utilisé cela comme l'une de mes options pour combiner le nom d'hôte et le nom de domaine pour créer un rapport, ajouté le texte générique à remplir lorsque le nom de domaine n'était pas capturé, c'était l'une des exigences des clients.

J'ai testé cela en utilisant 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
} 

Construit en utilisant les idées de la solution Miky Dinescu.

user3500031
la source
1

Nous avons implémenté le résultat suggéré à utiliser de cette manière:

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

Cependant, s'est avéré que cela ne fonctionne pas correctement lorsque le nom de l'ordinateur est plus long que 15 caractères et en utilisant le nom NetBios. Environment.MachineName ne renvoie qu'un nom partiel et le nom d'hôte de résolution renvoie le même nom d'ordinateur.

Après quelques recherches, nous avons trouvé une solution pour résoudre ce problème:

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

Cela a résolu tous les problèmes, y compris le nom de l'ordinateur.

btomas
la source
Cela lèvera une exception, et la plupart des autres solutions suggérées échoueront également, si vous avez un ordinateur auquel l'utilisateur a donné un nom contenant des caractères ne provenant pas de az, 0-9, '.', '-'. Attendez-vous donc à des problèmes si vous avez des utilisateurs en Asie ou similaire. GetHostName aura ces caractères remplacés par «?». C'est pourquoi je préfère GetHostByName ("localhost"). HostName qui montre le nom réel de l'ordinateur.
Göran
0

J'ai utilisé cette approche:

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

Aucune des réponses fournies que j'ai testées n'a fourni le suffixe DNS que je recherchais. Voici ce que j'ai trouvé.

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

Si vous voulez le ranger et gérer les exceptions, essayez ceci:

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
la source
2
"et gérer les exceptions" - FAIL.
Jörgen Sigvardsson
tu crois que catch gère l'exception!
Saher Ahwal
Non, je pense que vous devez décider vous-même de la manière dont vous voulez gérer les exceptions. Et si vous ne pouvez pas récupérer un nom de domaine, comment proposeriez-vous de le gérer?
Roger Willcocks
4
Enregistrez un rapport d'erreur et avertissez l'utilisateur que quelque chose s'est mal passé au lieu de fournir au code client des informations erronées.
dahvyd