Làm thế nào để tìm FQDN của máy cục bộ trong C # /. NET?


87

Làm thế nào bạn có thể lấy FQDN của một máy cục bộ trong C #?

Câu trả lời:


143

LƯU Ý: Giải pháp này chỉ hoạt động khi nhắm mục tiêu các khuôn khổ .NET 2.0 (và mới hơn).

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
}

CẬP NHẬT

Vì có nhiều người nhận xét rằng Câu trả lời của Sam ngắn gọn hơn nên tôi quyết định thêm một số nhận xét vào câu trả lời.

Điều quan trọng nhất cần lưu ý là mã tôi đã đưa ra không tương đương với mã sau:

Dns.GetHostEntry("LocalHost").HostName

Trong trường hợp chung khi máy được nối mạng và là một phần của miền, cả hai phương pháp nói chung sẽ tạo ra cùng một kết quả, trong các trường hợp khác, kết quả sẽ khác nhau.

Một tình huống mà đầu ra sẽ khác khi máy không phải là một phần của miền. Trong trường hợp này, Dns.GetHostEntry("LocalHost").HostNamesẽ trả về localhosttrong khi GetFQDN()phương thức trên sẽ trả về tên NETBIOS của máy chủ.

Sự khác biệt này rất quan trọng khi mục đích của việc tìm kiếm máy FQDN là để ghi thông tin hoặc tạo báo cáo. Hầu hết thời gian tôi sử dụng phương pháp này trong nhật ký hoặc báo cáo sau đó được sử dụng để ánh xạ thông tin trở lại một máy cụ thể. Nếu các máy không được nối mạng, mã localhostđịnh danh sẽ vô dụng, ngược lại tên cung cấp thông tin cần thiết.

Vì vậy, cuối cùng tùy thuộc vào mỗi người dùng phương pháp nào phù hợp hơn cho ứng dụng của họ, tùy thuộc vào kết quả họ cần. Nhưng để nói rằng câu trả lời này là sai vì không đủ ngắn gọn là tốt nhất là hời hợt.

Xem ví dụ trong đó đầu ra sẽ khác: http://ideone.com/q4S4I0


2
Sử dụng, Dns.GetHostEntry("LocalHost").HostNametôi luôn nhận được tên máy chủ (không phải netbios) với hậu tố tên miền chính. Điều này không phụ thuộc vào việc máy có thuộc miền, máy chủ DNS có thể truy cập được hay mạng lưới được kết nối hay không. Có lẽ tôi không hiểu lời giải thích của bạn nhưng kết quả là những gì tôi mong đợi. (Máy: W2008R2; .net 4.0; netbiosname: TESTNAME-VERYLO tên máy chủ: TESTNAME-VERYLONG)
marsh-wiggle

Tại sao bạn sử dụng Dns.GetHostName()for hostNamethay vì sử dụng thuộc HostNametính của IPGlobalPropertiesđối tượng bạn đã có, một dòng ở trên?
Xharlie

@Xharlie vì thuộc tính IPGlobalPropertiestên máy chủ trả về tên NetBIOS, trong khi Dns.GetHostName()trả về tên máy chủ DNS.
Mike Dinescu

2
các EndsWithkiểm tra được chia cho hostname kết thúc bằng các chữ cái giống như tên miền (ví dụ như một myhost chủ trong OST miền), có lẽ nên đượcEndsWith("." + domainName)
user3391859

6
Nếu domainName trống thì nó trả về hostName.. Nên có !String.isNullorEmpty(domainName)séc
RodgerTheGreat

63

Đơn giản hóa một chút mã của Miky D

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

4
Không giống như mã của Micky D, mã này trả về tên máy chủ với một điểm đầy đủ được thêm vào nếu máy không phải là thành viên của miền.
Bosco

1
Ngoài ra, điều này sử dụng tên NetBIOS thay vì tên máy chủ DNS. Tôi tin rằng tên NetBIOS chỉ phù hợp trong mạng LAN.
Sam

Có lẽ thêm a .Trim(".")vào dòng cuối cùng để loại bỏ. nếu nó tồn tại.
David d C e Freitas

28

Điều này được đề cập bởi bài báo này . Kỹ thuật này ngắn gọn hơn câu trả lời được chấp nhận và có lẽ đáng tin cậy hơn câu trả lời được bình chọn nhiều nhất tiếp theo. Lưu ý rằng theo như tôi hiểu, điều này không sử dụng tên NetBIOS, vì vậy nó phải phù hợp để sử dụng Internet.

.NET 2.0+

Dns.GetHostEntry("LocalHost").HostName

.NET 1.0 - 1.1

Dns.GetHostByName("LocalHost").HostName

@DexterLegaspi - Câu trả lời của Sam là một câu hay (tôi thậm chí còn tự giải mã nó) nhưng nó không tương đương với câu trả lời của tôi, cũng không nhất thiết phải tốt hơn. Vui lòng xem câu trả lời cập nhật của tôi để biết chi tiết.
Mike Dinescu

@MikeDinescu câu hỏi là làm thế nào để có được FQDN, nghĩa là máy đó nằm trên mạng và là một phần của miền. câu trả lời được chấp nhận làm công việc nhưng câu trả lời của Sam là nhiều hơn "chính xác" (đối với việc thiếu một thuật ngữ tốt hơn)
Dexter Legaspi

3
Đây là câu trả lời chính xác! nhưng thay vì làm Dns.GetHostEntry("LocalHost").HostNamebạn tốt hơn thông qua một chuỗi rỗng như vậy:Dns.GetHostEntry("").HostName
paulgutten

17

Đây là nó trong PowerShell, vì cái lỗi của nó:

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

15

Và đối với Framework 1.1 thì đơn giản như sau:

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

Và sau đó loại bỏ tên NETBIOS của máy để chỉ lấy tên miền


Ở đây vào năm 2013, đã GetHostByName("localhost")được xóa sổ. VS 2010 đề nghị tôi sử dụng GetHostEntry("localhost")thay thế, hoạt động tốt.
piedar

@piedar, bạn có thể đã bỏ lỡ một chút về điều này đối với .NET 1.1.
Sam

Tôi muốn thêm thông tin cập nhật vào câu trả lời này, vì nó là câu trả lời đơn giản nhất và do đó tôi yêu thích nhất. Tôi có lẽ đã không cuộn đủ xa để xem câu trả lời của bạn, điều này thực sự khiến nhận xét của tôi trở nên không cần thiết.
piedar

8

Bạn có thể thử những cách sau:

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

Shoud này cung cấp cho bạn FQDN của máy cục bộ hiện tại (hoặc bạn có thể chỉ định bất kỳ máy chủ nào).


5

Một chút cải tiến cho câu trả lời của Matt Z để một điểm dừng đầy đủ theo sau không được trả lại nếu máy tính không phải là thành viên của miền:

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

Lưu ý rằng tôi nghĩ rằng điều này sử dụng tên máy chủ NetBIOS, vì vậy nó có thể không phù hợp để sử dụng Internet.
Sam

2

Sử dụng đây là một trong những lựa chọn của tôi để kết hợp tên máy chủ và tên miền để xây dựng báo cáo, thêm văn bản chung chung để điền vào khi chưa nắm bắt được tên miền, đây là một trong những yêu cầu của khách hàng.

Tôi đã thử nghiệm điều này bằng 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
} 

Được xây dựng bằng cách sử dụng ý tưởng từ giải pháp Miky Dinescu.


1

Chúng tôi đã triển khai kết quả được đề xuất để sử dụng theo cách này:

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

Tuy nhiên, hóa ra điều này không hoạt động đúng khi tên máy tính dài hơn 15 ký tự và sử dụng tên NetBios. Môi trường.MachineName chỉ trả về một phần tên và phân giải tên máy chủ trả về cùng một tên máy tính.

Sau một số nghiên cứu, chúng tôi đã tìm ra giải pháp để khắc phục sự cố này:

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

Điều này giải quyết tất cả các vấn đề bao gồm cả tên máy tính.


Điều này sẽ tạo ra một ngoại lệ và hầu hết các giải pháp khác được đề xuất cũng sẽ không thành công, nếu bạn có một máy tính được người dùng đặt tên có chứa các ký tự không phải từ az, 0-9, '.', '-'. Vì vậy, hãy mong đợi sự cố nếu bạn có người dùng ở Châu Á hoặc tương tự. GetHostName sẽ có các ký tự đó được thay thế bằng '?'. Đó là lý do tại sao tôi thích GetHostByName ("localhost"). HostName hiển thị tên máy tính thực.
Göran

0

Tôi đã sử dụng cách tiếp cận này:

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

0

Không có câu trả lời nào được cung cấp mà tôi đã kiểm tra thực sự cung cấp hậu tố DNS mà tôi đang tìm kiếm. Đây là những gì tôi nghĩ ra.

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

-9

Nếu bạn muốn thu gọn nó và xử lý các ngoại lệ, hãy thử cách này:

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
"và xử lý các trường hợp ngoại lệ" - FAIL.
Jörgen Sigvardsson

bạn nghĩ rằng catch của chính nó xử lý ngoại lệ!
Saher Ahwal

Không, tôi nghĩ rằng bạn muốn xử lý các trường hợp ngoại lệ như thế nào là điều bạn cần tự quyết định. Và nếu bạn không thể lấy lại tên miền, BẠN sẽ đề xuất xử lý nó như thế nào?
Roger Willcocks,

4
Ghi báo cáo lỗi và cảnh báo người dùng rằng đã xảy ra sự cố thay vì cung cấp mã máy khách với thông tin bị lỗi.
dahvyd 21/10/12
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.