C # ile yerel bir makinenin FQDN'sini nasıl elde edebilirsiniz?
Yanıtlar:
NOT: Bu çözüm yalnızca .NET 2.0 (ve daha yeni) çerçevelerini hedeflerken çalışır.
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
}
GÜNCELLEME
Pek çok kişi Sam'in Cevabının daha özlü olduğu yorumunu yaptığından , cevaba bazı yorumlar eklemeye karar verdim.
Unutulmaması gereken en önemli şey verdiğim kodun aşağıdaki kodla eşdeğer olmamasıdır:
Dns.GetHostEntry("LocalHost").HostName
Makinenin ağa bağlı olduğu ve bir alanın parçası olduğu genel durumda, her iki yöntem de genellikle aynı sonucu verirken, diğer senaryolarda sonuçlar farklı olacaktır.
Çıktının farklı olacağı bir senaryo, makinenin bir alanın parçası olmadığı durumdur. Bu durumda, Dns.GetHostEntry("LocalHost").HostName
geri dönecek localhost
iken GetFQDN()
yöntem yukarıda ana bilgisayarın NETBIOS adını döndürür.
Makine FQDN'sini bulmanın amacı bilgileri günlüğe kaydetmek veya bir rapor oluşturmak olduğunda bu ayrım önemlidir. Çoğu zaman bu yöntemi, daha sonra bilgileri belirli bir makineye geri eşlemek için kullanılan günlüklerde veya raporlarda kullandım. Makineler ağa bağlı değilse, localhost
tanımlayıcı işe yaramaz, oysa isim gerekli bilgiyi verir.
Sonuç olarak, hangi sonuca ihtiyaç duyduklarına bağlı olarak, hangi yöntemin uygulamaları için daha uygun olduğu her kullanıcıya bağlıdır. Ancak bu cevabın yeterince özlü olmamanın yanlış olduğunu söylemek, en iyi ihtimalle yüzeyseldir.
Çıktının farklı olacağı bir örneğe bakın: http://ideone.com/q4S4I0
Dns.GetHostName()
için hostName
kullanmak yerine HostName
malı IPGlobalProperties
bir satır yukarıda zaten sahip nesne?
IPGlobalProperties
hostname özelliği NetBIOS adını Dns.GetHostName()
döndürürken, DNS ana bilgisayar adını döndürür.
EndsWith
Etki alanı adıyla aynı harflerle biten ana bilgisayar adları için kontrol geçersizdir (örneğin, OST etki alanındaki bir ana bilgisayar MYHOST), muhtemelenEndsWith("." + domainName)
hostName.
. Bir !String.isNullorEmpty(domainName)
çek olmalı
Miky D'nin kodunun hafif bir basitleştirmesi
public static string GetLocalhostFqdn()
{
var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
return string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
}
.Trim(".")
son satıra bir ekleyerek . eğer varsa.
Bu, bu makalenin kapsamındadır . Bu teknik, kabul edilen cevaptan daha kısadır ve muhtemelen bir sonraki en çok oylanan cevaptan daha güvenilirdir. Anladığım kadarıyla, bu kadar geldiğini hatırlatırız gelmez NetBIOS adlarını kullanın, bu nedenle internet kullanım için uygun olmalıdır.
Dns.GetHostEntry("LocalHost").HostName
Dns.GetHostByName("LocalHost").HostName
Dns.GetHostEntry("LocalHost").HostName
boş bir dizeyi böyle Dns.GetHostEntry("").HostName
Ve Framework 1.1 için bu kadar basit:
System.Net.Dns.GetHostByName("localhost").HostName
Ve sonra yalnızca domainName'i almak için makine NETBIOS adını kaldırın
GetHostByName("localhost")
kullanımdan kaldırıldı. VS 2010 GetHostEntry("localhost")
bunun yerine kullanmamı önerdi , bu da iyi çalışıyor.
Matt Z'nin yanıtında ufak bir iyileştirme yapıldı, böylece bilgisayar bir etki alanının üyesi değilse sondaki bir nokta döndürülmedi:
public static string GetLocalhostFqdn()
{
var ipProperties = IPGlobalProperties.GetIPGlobalProperties();
return string.IsNullOrWhiteSpace(ipProperties.DomainName) ? ipProperties.HostName : string.Format("{0}.{1}", ipProperties.HostName, ipProperties.DomainName);
}
Bunu, bir rapor oluşturmak için ana bilgisayar adını ve etki alanı adını birleştirme seçeneklerimden biri olarak kullandım, etki alanı adı yakalanmadığında doldurulacak genel metni ekledi, bu müşterilerin gereksinimlerinden biriydi.
Bunu C # 5.0, .Net 4.5.1 kullanarak test ettim
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
}
Miky Dinescu çözümündeki fikirler kullanılarak oluşturulmuştur.
Bu şekilde kullanmak için önerilen sonucu uyguladık:
return System.Net.Dns.GetHostEntry(Environment.MachineName).HostName;
Ancak, bilgisayar adı 15 karakterden uzun olduğunda ve NetBios adı kullanıldığında bunun doğru çalışmadığı ortaya çıktı. Environment.MachineName yalnızca kısmi adı döndürür ve ana bilgisayar adını çözümlemek aynı bilgisayar adını döndürür.
Biraz araştırdıktan sonra bu sorunu çözmek için bir çözüm bulduk:
System.Net.Dns.GetHostEntry(System.Net.Dns.GetHostName()).HostName
Bu, bilgisayar adı dahil tüm sorunları çözdü.
Test ettiğim yanıtların hiçbiri aradığım DNS son ekini gerçekten sağlamadı. İşte bulduğum şey.
public static string GetFqdn()
{
var networkInterfaces = NetworkInterface.GetAllNetworkInterfaces();
var ipprops = networkInterfaces.First().GetIPProperties();
var suffix = ipprops.DnsSuffix;
return $"{IPGlobalProperties.GetIPGlobalProperties().HostName}.{suffix}";
}
FQ Ana Bilgisayar Adı / Ana Bilgisayar Adı / NetBIOS MakineAdı / EtkiAlanıAdı çevresindeki tüm durumları işlemek için yöntem koleksiyonum
/// <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;
}
Düzenlemek ve istisnaları ele almak istiyorsanız, şunu deneyin:
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;
}
Dns.GetHostEntry("LocalHost").HostName
her zaman ana alan adını (netbios değil) birincil alan sonekiyle alırım. Bu, makinenin bir etki alanının parçası olup olmadığına, bir DNS sunucusuna ulaşılabilir olup olmadığına veya ağ bağlantısının bağlı olmasına bağlı değildir. Muhtemelen açıklamanızı anlamıyorum ama sonuç beklediğim şey. (Makine: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO ana bilgisayar adı: TESTNAME-VERYLONG)