21

バックグラウンド

コンピューターから一意の識別子を取得しようとしていますが、毎回同じMACアドレスを確実に返すことができるようにしたいと考えています。私はMACアドレスを使用する理由があり、代替の一意のIDメソッドに関する多くの投稿を読んだことがあります(そして、ネットワークカードがないかどうかを検討しました)。

問題

問題は.NETにあり、特定のNetworkInterfaceが、特定のVPNまたはWiFiネットワークに接続したときに追加される「NortelIPSECSHMアダプター-パケットスケジューラミニポート」などの物理ハードウェアネットワークカードであるかどうかを判断できません。

次のようなコードを使用してMacアドレスを取得する方法を知っています。

    foreach (NetworkInterface nic in NetworkInterface.GetAllNetworkInterfaces())
    {
        log.Debug("NIC " + nic.OperationalStatus + " " + nic.NetworkInterfaceType + " " + nic.Speed + " " + nic.GetPhysicalAddress() + " " + nic.Description);
    }

当然のことながら、内部ネットワークカードを確実に取得する方法は100%ありませんが、MACアドレスを選択して、変更される可能性が最も低い特定のマシンのMACアドレスを返したいと思います。Wi-Fiに接続されているかどうか...何らかのテザー接続を介して接続されているかどうか...または新しいインターフェイスを追加する新しいVPNソフトウェアをインストールするかどうかなどの要因とは関係ありません。

考慮される戦略

1)「アップ」である最初のインターフェースを選択します。「パケットミニポート」が常に稼働しているため、これは私のラップトップでは失敗します。さらに、電話をラップトップにつなぐと、これも最初のカードとして表示されます。

2)最も適切なタイプを選択してください...これは失敗しますb / c基本的に、WiFiアダプターと私のiPHoneテザリングインターネット接続を含むすべてが「イーサネット」として表示されます。

3)IPアドレスを持つNICを選択します。いくつかの理由で失敗します:1)ネットワークカードがLANに接続されていない可能性があります2)IPアドレスを持つ可能性のある複数のNICがあります。

4)すべてのMACアドレスを送信するだけです...問題は、インストールされているソフトウェアに基づいてリストが変更され、比較が困難になることです。

5)最速のMACアドレスを選択します。これがおそらく私の最善の策だと思います。通常、最速のインターフェースが最も永続的であると言っても過言ではありません。

または、.NETで物理カードを検出する他の方法があるかもしれません。または、別の情報を提供するAPI呼び出しを推奨できる場合は、他のAPI呼び出しを呼び出すことを検討します。

他のアイデアはありますか?

ここで示すのは、iPhoneをテザー接続したときの上記のサンプルコードの出力です。

DEBUG - NIC Down Ethernet 500000     0021E98BFBEF Apple Mobile Device Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up   Ethernet 10000000   444553544200 Nortel IPSECSHM Adapter - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 54000000   00166FAC94C7 Intel(R) PRO/Wireless 2200BG Network Connection - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 1000000000 0016D326E957 Broadcom NetXtreme Gigabit Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up   Loopback 10000000  MS TCP Loopback interface

iPhoneが接続されていない場合:

DEBUG - NIC Up   Ethernet 10000000   444553544200 Nortel IPSECSHM Adapter - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 54000000   00166FAC94C7 Intel(R) PRO/Wireless 2200BG Network Connection - Packet Scheduler Miniport
DEBUG - NIC Down Ethernet 1000000000 0016D326E957 Broadcom NetXtreme Gigabit Ethernet - Packet Scheduler Miniport
DEBUG - NIC Up   Loopback 10000000  MS TCP Loopback interface
4

5 に答える 5

12

これが私の方法です。物理カードがPCIインターフェースに接続されているという事実を利用しています。

ManagementObjectSearcher searcher = new ManagementObjectSearcher
    ("Select MACAddress,PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND PNPDeviceID IS NOT NULL");
ManagementObjectCollection mObject = searcher.Get();

foreach (ManagementObject obj in mObject)
{
    string pnp = obj["PNPDeviceID"].ToString();
    if (pnp.Contains("PCI\\"))
    {
        string mac = obj["MACAddress"].ToString();
        mac = mac.Replace(":", string.Empty);
        return mac;
    }
}
于 2010-08-20T11:23:01.897 に答える
2

MACアドレスの最初の3バイトはメーカーIDです。目的に適さないことがわかっている特定のメーカーIDをブラックリストに登録し、それらのインターフェースを無視することができます。

VPNインターフェイスがギガビットの速度であると報告できなかった理由がないため、速度に依存することはお勧めできません。

于 2009-10-14T22:31:39.373 に答える
0

MACアドレスは物理ハードウェアアドレスです。このPCでテストすることはできませんが、仮想接続が追加された場合、実際のハードウェアではないため、新しいMACアドレスを取得できるとは思いません。別の接続になりますが、別のMACアドレスにはなりません。

したがって、毎回同じMACアドレスを取得することを保証するには、マシンに接続されている同じハードウェアと、同じアルゴリズムを使用してそのハードウェアから選択する必要があります。

于 2009-10-14T18:43:36.897 に答える
0

私もこの問題を検討してきましたが、永続的な状態がなければ、安定したMACを維持するのは難しいと思います。

私が試している解決策は、アダプターの注文で最初に見つかったNICを取得し、それを使用して保存することです。次に、後続のUUID生成で、最初ではなくてもスタック内のどこかに見つかった場合は、保存されたMACを使用します。このようにして、アダプターの注文を移動でき、安定したMAC(ライセンスモジュールなど)に依存するものが何であれ、爆発する心配はありません。

保存されたMACがスタックに見つからない場合、それは破棄され、バインド順の最初のMACを使用して最初からやり直します。

于 2012-12-28T16:15:06.410 に答える
0
 public static string GetMacAddressPhysicalNetworkInterface()
    {

        ManagementObjectSearcher searcher = new ManagementObjectSearcher
        ("Select MACAddress,PNPDeviceID FROM Win32_NetworkAdapter WHERE MACAddress IS NOT NULL AND" +
         " PNPDeviceID IS NOT NULL AND" +
         " PhysicalAdapter = true");
        ManagementObjectCollection mObject = searcher.Get();

        string macs = (from ManagementObject obj in mObject
                let pnp = obj["PNPDeviceID"].ToString()
                where !(pnp.Contains("ROOT\\"))
                //where  pnp.Contains("PCI\\")  || pnp.Contains("USB\\")
                select obj).Select(obj => obj["MACAddress"].ToString())
            .Aggregate<string, string>(null, (mac, currentMac) => mac + currentMac.Replace(":", string.Empty) + ",");

        return !string.IsNullOrEmpty(macs) ? macs.Substring(0, macs.Length - 1) : macs;
    }

    public static NetworkInterface GetPhysicalNetworkInterface(string macAddressPhysicalNetworkInterface)
    {
        return NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(currentNetworkInterface => string.Equals(currentNetworkInterface.GetPhysicalAddress().ToString(), macAddressPhysicalNetworkInterface, StringComparison.CurrentCultureIgnoreCase));
    }
于 2017-08-23T07:06:50.247 に答える