web-dev-qa-db-ja.com

ローカルIPアドレスのクエリ

Windows 8 WinRT/Metroアプリから実際のローカルIPアドレス(つまり、ループバックアドレスではない)を知る必要があります。これが必要な理由はいくつかあります。最も簡単なのは、アプリのUIに、「ローカルネットワークのIPアドレスは[コードから照会されたIP]」のようなテキストを表示したいということです。

また、いくつかの追加のネットワーク通信にもアドレスを使用します。これらの通信は完全に有効です。コントロールパネルでIPアドレスを確認し、それをアプリにハードコーディングすればすべて機能するからです。ダイアログでユーザーにアドレスを確認して手動で入力するように求めることは、私が本当に避けたいことです。

プログラムでアドレスを取得するのは複雑な作業ではないと思いますが、検索エンジンとStackOverflowのスキルは空になりつつあります。

この時点で、UDPブロードキャスト/リッスンループを実行して自分の要求を聞き、そこからアドレスを抽出することを検討し始めていますが、それは本当にハッキーな応急修理のようです。新しいWinRTのもののどこかに私をそこに導くAPIはありますか?

「WinRTアプリ。つまり、_Dns.GetHostEntry_やNetworkInterface.GetAllInterfaces()などの一般的なメカニズムが機能しないことを意味します。

31
ctacke

よく調べた結果、 NetworkInformation および HostName を使用して必要な情報を見つけました。

NetworkInformation.GetInternetConnectionProfile ローカルマシンで現在使用されているインターネット接続に関連付けられている接続プロファイルを取得します。

NetworkInformation.GetHostNames ホスト名のリストを取得します。明らかではありませんが、これには文字列としてIPv4アドレスとIPv6アドレスが含まれます。

この情報を使用して、次のようにインターネットに接続されているネットワークアダプタのIPアドレスを取得できます。

public string CurrentIPAddress()
{
    var icp = NetworkInformation.GetInternetConnectionProfile();

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

        if (hostname != null)
        {
            // the ip address
            return hostname.CanonicalName;
        }
    }

    return string.Empty;
}

HostName にはCanonicalName、DisplayName、RawNameのプロパティがありますが、これらはすべて同じ文字列を返すように見えることに注意してください。

次のようなコードで複数のアダプタのアドレスを取得することもできます。

private IEnumerable<string> GetCurrentIpAddresses()
{
    var profiles = NetworkInformation.GetConnectionProfiles().ToList();

    // the Internet connection profile doesn't seem to be in the above list
    profiles.Add(NetworkInformation.GetInternetConnectionProfile());

    IEnumerable<HostName> hostnames =
        NetworkInformation.GetHostNames().Where(h => 
            h.IPInformation != null &&
            h.IPInformation.NetworkAdapter != null).ToList();

    return (from h in hostnames
            from p in profiles
            where h.IPInformation.NetworkAdapter.NetworkAdapterId ==
                  p.NetworkAdapter.NetworkAdapterId
            select string.Format("{0}, {1}", p.ProfileName, h.CanonicalName)).ToList();
}
34
Phil

受け入れられた答えについて、あなたはこれが必要です:

HostName localHostName = NetworkInformation.GetHostNames().FirstOrDefault(h =>
                    h.IPInformation != null &&
                    h.IPInformation.NetworkAdapter != null);

ローカルIPアドレスは次の方法で取得できます。

string ipAddress = localHostName.RawName; //XXX.XXX.XXX.XXX

使用される名前空間:

using System.Linq;
using Windows.Networking;
using Windows.Networking.Connectivity;
1
Bruno Lemos