จะหา FQDN ของเครื่องใน C # /. NET ได้อย่างไร?


คำตอบ:


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").HostNameI get always the hostname (ไม่ใช่ netbios) พร้อมคำต่อท้ายโดเมนหลัก สิ่งนี้ไม่ได้ขึ้นอยู่กับว่าเครื่องเป็นส่วนหนึ่งของโดเมนเซิร์ฟเวอร์ DNS สามารถเข้าถึงได้หรือเชื่อมต่อกับ netzwork ฉันอาจไม่เข้าใจคำอธิบายของคุณ แต่ผลลัพธ์คือสิ่งที่ฉันคาดหวัง (เครื่อง: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO hostname: TESTNAME-VERYLONG)
marsh-wiggle

ทำไมคุณใช้Dns.GetHostName()สำหรับhostNameแทนการใช้HostNameทรัพย์สินของIPGlobalPropertiesวัตถุที่คุณมีอยู่แล้วหนึ่งบรรทัดข้างต้น
Xharlie

@Xharlie เนื่องจากIPGlobalPropertiesคุณสมบัติ hostname ส่งคืนชื่อ NetBIOS ในขณะที่Dns.GetHostName()ส่งคืนชื่อโฮสต์ DNS
Mike Dinescu

2
การEndsWithตรวจสอบเสียสำหรับชื่อโฮสต์ที่ลงท้ายด้วยตัวอักษรเดียวกับชื่อโดเมน (เช่นโฮสต์ MYHOST ใน OST ของโดเมน) น่าจะเป็นEndsWith("." + domainName)
user3391859

7
หาก 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 ซึ่งจะส่งคืนชื่อโฮสต์พร้อมกับ fullstop ต่อท้ายหากเครื่องไม่ได้เป็นสมาชิกของโดเมน
Bosco

1
นอกจากนี้สิ่งนี้ใช้ชื่อ NetBIOS แทนชื่อโฮสต์ DNS ฉันเชื่อว่าชื่อ NetBIOS เหมาะสำหรับ LAN เท่านั้น
แซม

บางทีอาจเพิ่ม a .Trim(".")ในบรรทัดสุดท้ายเพื่อกำจัดไฟล์. ถ้ามีอยู่
David d C e Freitas

29

นี้ถูกปกคลุมด้วยบทความนี้ เทคนิคนี้สั้นกว่าคำตอบที่ยอมรับและน่าจะเชื่อถือได้มากกว่าคำตอบที่ได้รับการโหวตมากที่สุดถัดไป โปรดทราบว่าเท่าที่ฉันเข้าใจสิ่งนี้ไม่ได้ใช้ชื่อ NetBIOS ดังนั้นจึงควรเหมาะสำหรับการใช้งานอินเทอร์เน็ต

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName

@DexterLegaspi - คำตอบของ Sam เป็นคำตอบที่ดี (ฉันได้อัปเดตด้วยตัวเอง) แต่มันไม่เทียบเท่ากับคำตอบของฉันหรือไม่จำเป็นต้องดีกว่า โปรดดูคำตอบที่อัปเดตของฉันสำหรับรายละเอียด
Mike Dinescu

@MikeDinescu คำถามคือวิธีรับ FQDN ซึ่งหมายความว่าเครื่องอยู่บนเครือข่ายและเป็นส่วนหนึ่งของโดเมน คำตอบที่ยอมรับได้ผล แต่คำตอบของ Sam นั้น "แม่นยำกว่า" (สำหรับการไม่มีคำที่ดีกว่า)
Dexter Legaspi

4
นี่คือคำตอบที่ถูกต้อง! แต่แทนที่จะให้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 ของเครื่องเพื่อดึงเฉพาะ domainName


ที่นี่ในปี 2013 GetHostByName("localhost")ล้าสมัย VS 2010 แนะนำให้ฉันใช้GetHostEntry("localhost")แทนซึ่งใช้งานได้ดี
piedar

@piedar คุณอาจพลาดบิตเกี่ยวกับสิ่งนี้สำหรับ. NET 1.1
แซม

ฉันต้องการเพิ่มข้อมูลที่อัปเดตให้กับคำตอบนี้เนื่องจากเป็นวิธีที่ง่ายที่สุดและเป็นสิ่งที่ฉันชอบ ฉันอาจไม่ได้เลื่อนไปไกลพอที่จะเห็นคำตอบของคุณซึ่งทำให้ความคิดเห็นของฉันไม่จำเป็น
piedar

8

คุณสามารถลองทำสิ่งต่อไปนี้:

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

shoud นี้ให้ FQDN ของเครื่องท้องถิ่นปัจจุบัน (หรือคุณสามารถระบุโฮสต์ใดก็ได้)


5

คำตอบของ Matt Z มีการปรับปรุงเล็กน้อยเพื่อให้ไม่ส่งคืน full stop หากคอมพิวเตอร์ไม่ได้เป็นสมาชิกของโดเมน:

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
} 

สร้างขึ้นโดยใช้แนวคิดจากโซลูชัน Miky Dinescu


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 ซึ่งแสดงชื่อคอมพิวเตอร์จริง
Göran

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}";
}

0

ชุดวิธีการจัดการทุกกรณีรอบ ​​FQ Hostname / Hostname / NetBIOS Machinename / DomainName

    /// <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;
    }

-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
Jörgen Sigvardsson

คุณคิดว่าจับด้วยตัวเองจัดการข้อยกเว้น!
Saher Ahwal

ไม่ฉันคิดว่าคุณต้องการจัดการข้อยกเว้นอย่างไรเป็นสิ่งที่คุณต้องตัดสินใจด้วยตัวเอง และถ้าคุณไม่สามารถเรียกชื่อโดเมนกลับคืนมาได้คุณจะเสนอให้จัดการกับมันอย่างไร?
Roger Willcocks

4
บันทึกรายงานข้อผิดพลาดและเตือนผู้ใช้ว่ามีบางอย่างผิดพลาดแทนที่จะส่งรหัสไคลเอ็นต์ด้วยข้อมูลที่ผิดพลาด
dahvyd
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.