Как найти локальный IP-адрес в проекте Win 10 UWP

В настоящее время я пытаюсь перенести приложение административной консоли на приложение Win 10 UWP. У меня возникли проблемы с использованием System.Net.Dns из следующего кода консоли.

Как я могу получить IP-адреса устройств

Вот код консольного приложения, которое я пытаюсь перенести.

public static string GetIP4Address()
{
    string IP4Address = String.Empty;
    foreach (IPAddress IPA in Dns.GetHostAddresses(Dns.GetHostName()))
    {
        if (IPA.AddressFamily == AddressFamily.InterNetwork)
        {
            IP4Address = IPA.ToString();
            break;
        }
    }
    return IP4Address;
}

person Daniel Jerome    schedule 18.11.2015    source источник


Ответы (3)


Вы можете попробовать вот так:

private string GetLocalIp()
{
    var icp = NetworkInformation.GetInternetConnectionProfile();

    if (icp?.NetworkAdapter == null) return null;
    var hostname =
        NetworkInformation.GetHostNames()
            .SingleOrDefault(
                hn =>
                    hn.IPInformation?.NetworkAdapter != null && hn.IPInformation.NetworkAdapter.NetworkAdapterId
                    == icp.NetworkAdapter.NetworkAdapterId);

    // the ip address
    return hostname?.CanonicalName;
}

ответ выше тоже правильный

person John Zhang    schedule 18.11.2015
comment
Мне сложно решить, какой из них использовать, поэтому я вернусь к галочке ответа после небольшого эксперимента. - person Daniel Jerome; 18.11.2015
comment
Похоже, что они оба работают, но я отметил второй, потому что он был в методе, который возвращал строку, как в моем исходном примере. Это также немного больше похоже на мой стиль программирования. Спасибо, ребята, вы спасли положение. - person Daniel Jerome; 18.11.2015
comment
Этот код действительно и наверняка возвращает локальный IP-адрес, «другой код» возвращает IP-адрес, который ваше устройство или локальная сеть использует для выхода в Интернет. - person JuanK; 05.01.2016
comment
Это вызывает исключение LINQ - в моем случае последовательность содержит более одного совпадающего элемента (как я писал в другом комментарии, у меня также есть виртуальный коммутатор, настроенный VirtualBox в моем списке адаптеров). Я изменил его на FirstOrDefault вместо SingleOrDefault, чтобы обойти это, и он вернул адрес Ipv6. См. Мой ответ, чтобы узнать, как получить Ipv4 one - person George Birbilis; 01.09.2017
comment
также этот другой ответ от @panda может вернуть неправильный ответ (в моем случае адрес виртуального коммутатора, настроенного VirtualBox) - person George Birbilis; 01.09.2017

Используйте это, чтобы получить IP-адрес хоста в приложении UWP, я это тестировал:

    foreach (HostName localHostName in NetworkInformation.GetHostNames())
    {
        if (localHostName.IPInformation != null)
        {
            if (localHostName.Type == HostNameType.Ipv4)
            {
                textblock.Text = localHostName.ToString();
                break;
            }
        }
    }

И см. Документ API здесь

person panda    schedule 18.11.2015
comment
это не сработает, если вы скажете VirtualBox, в моем случае выражение NetworkInformation.GetHostNames (). FirstOrDefault (name = ›name.Type == HostNameType.Ipv4) ?. DisplayName ?? ???; возвращал IP-адрес настройки виртуального коммутатора VirtualBox - person George Birbilis; 01.09.2017
comment
Чтобы объяснить, почему это работает, документы говорят: Свойство IPInformation устанавливается только тогда, когда объект HostName является локальным адресом IPv4 или IPv6, возвращаемым методом GetHostNames. Это свойство представляет объект IPInformation для локального IP-адреса. Если объект HostName не является локальным адресом IPv4 или IPv6, это свойство будет пустым. - person dantechguy; 06.10.2020
comment
Могу я спросить, поскольку у меня несколько адресов DCHP (для Wi-Fi и Ethernet), как я могу всегда получать адрес Wi-Fi? Поскольку цикл разрывается при первом экземпляре, это потому, что адрес Wi-Fi всегда будет первым? - person dantechguy; 07.10.2020

на основе ответа @John Zhang, но с исправлением, чтобы не выдавать ошибку LINQ о нескольких совпадениях и возвращать адрес Ipv4:

   public static string GetFirstLocalIp(HostNameType hostNameType = HostNameType.Ipv4)
    {
        var icp = NetworkInformation.GetInternetConnectionProfile();

        if (icp?.NetworkAdapter == null) return null;
        var hostname =
            NetworkInformation.GetHostNames()
                .FirstOrDefault(
                    hn =>
                        hn.Type == hostNameType &&
                        hn.IPInformation?.NetworkAdapter != null && 
                        hn.IPInformation.NetworkAdapter.NetworkAdapterId == icp.NetworkAdapter.NetworkAdapterId);

        // the ip address
        return hostname?.CanonicalName;
    }

очевидно, вы можете передать HostNameType.Ipv6 вместо Ipv4, который является значением параметра по умолчанию (неявным), чтобы получить адрес Ipv6.

person George Birbilis    schedule 01.09.2017
comment
обратите внимание, что после того, как я добавил проверку HostNameType в запрос LINQ, он перестал генерировать исключение для нескольких совпадений, но для безопасности я изменил SingleOrDefault на FirstOrDefault - person George Birbilis; 01.09.2017
comment
Интересно, почему кто-то проголосовал против этого ответа, который исправляет другие (который возвращает неправильные IP-адреса) - person George Birbilis; 08.09.2017
comment
Это лучший ответ. Не уверен, почему это было отвергнуто, поскольку ваш ответ - лучший код для большинства сценариев. Кроме того, FirstOrDefault - лучший метод LINQ для использования и здесь, поскольку на машине может быть несколько IP-адресов IPV4 или IPV6. Вызовите функцию GetFirstLocalIP (), и все будет хорошо. - person David Glass; 07.01.2018
comment
действительно, переименован - person George Birbilis; 07.10.2020