Как программно выбрать сетевую карту, подключенную к Интернету в .NET

Я хочу программно выбрать сетевую карту, подключенную к Интернету. Мне это нужно, чтобы отслеживать, сколько трафика проходит через карту. Это то, что я использую для получения имен экземпляров

var category = new PerformanceCounterCategory("Network Interface");
String[] instancenames = category.GetInstanceNames();

И вот так instancenames выглядит на моей машине

[0]    "6TO4 Adapter"    
[1]    "Internal"    
[2]    "isatap.{385049D5-5293-4E76-A072-9F7A15561418}"    
[3]    "Marvell Yukon 88E8056 PCI-E Gigabit Ethernet Controller"    
[4]    "isatap.{0CB9C3D2-0989-403A-B773-969229ED5074}"    
[5]    "Local Area Connection - Virtual Network"    
[6]    "Teredo Tunneling Pseudo-Interface"

Я хочу, чтобы решение было надежным и работало на других ПК, я бы также предпочел .NET. Я нашел другие решения, но они кажутся более сложными для цели

  1. Используйте C ++ или WMI.
  2. Анализировать вывод netstat

Есть ли еще что-нибудь?

Видите, я уже упоминал о некоторых доступных решениях. Я спрашиваю, есть ли что-то еще, более простое и надежное (например, НЕ C ++, WMI или вывод консольного приложения для синтаксического анализа)


person oleksii    schedule 12.05.2011    source источник
comment
возможный дубликат Как определить, какой сетевой адаптер подключен к Интернету   -  person Matt Ball    schedule 12.05.2011
comment
@Matt Ball Это не дубликат, я упомянул вашу ссылку в своем вопросе (в других решениях). Я ищу простой подход .NET.   -  person oleksii    schedule 13.05.2011


Ответы (1)


В итоге я использовал WMI и вызов внешней функции, лучшего решения не нашел. Вот мой код, если кому-то интересно.

using System;
using System.Collections.Generic;
using System.Diagnostics.Contracts;
using System.Linq;
using System.Management;
using System.Net;
using System.Net.Sockets;
using System.Runtime.InteropServices;

using log4net;

namespace Networking
{
    internal class NetworkCardLocator
    {
        [DllImport("iphlpapi.dll", CharSet = CharSet.Auto)]
        public static extern int GetBestInterface(UInt32 DestAddr, out UInt32 BestIfIndex);

        private static ILog log = OperationLogger.Instance();

        /// <summary>
        /// Selectes the name of the connection that is used to access internet or LAN
        /// </summary>
        /// <returns></returns>
        internal static string GetConnectedCardName()
        {
            uint idx = GetConnectedCardIndex();
            string query = String.Format("SELECT * FROM Win32_NetworkAdapter WHERE InterfaceIndex={0}", idx);
            var searcher = new ManagementObjectSearcher
            {
                Query = new ObjectQuery(query)
            };

            try
            {
                ManagementObjectCollection adapterObjects = searcher.Get();

                var names = (from ManagementObject o in adapterObjects
                             select o["Name"])
                            .Cast<string>()
                            .FirstOrDefault();

                return names;
            }
            catch (Exception ex)
            {
                log.Fatal(ex);
                throw;
            }
        }

        private static uint GetConnectedCardIndex()
        {
            try
            {
                string localhostName = Dns.GetHostName();
                IPHostEntry ipEntry = Dns.GetHostEntry(localhostName);
                IPAddress[] addresses = ipEntry.AddressList;
                var address = GetNeededIPAddress(addresses);
                uint ipaddr = IPAddressToUInt32(address);
                uint interfaceindex;
                GetBestInterface(ipaddr, out interfaceindex);

                return interfaceindex;
            }
            catch (Exception ex)
            {
                log.Fatal(ex);
                throw;
            }
        }

        private static uint IPAddressToUInt32(IPAddress address)
        {
            Contract.Requires<ArgumentNullException>(address != null);

            try
            {
                byte[] byteArray1 = IPAddress.Parse(address.ToString()).GetAddressBytes();
                byte[] byteArray2 = IPAddress.Parse(address.ToString()).GetAddressBytes();
                byteArray1[0] = byteArray2[3];
                byteArray1[1] = byteArray2[2];
                byteArray1[2] = byteArray2[1];
                byteArray1[3] = byteArray2[0];
                return BitConverter.ToUInt32(byteArray1, 0);
            }
            catch (Exception ex)
            {
                log.Fatal(ex);
                throw;
            }
        }

        private static IPAddress GetNeededIPAddress(IEnumerable<IPAddress> addresses)
        {
            var query = from address in addresses
                        where address.AddressFamily == AddressFamily.InterNetwork
                        select address;

            return query.FirstOrDefault();
        }
    }
}
person oleksii    schedule 16.05.2011
comment
Вместо WMI вы можете использовать System.Net.NetworkInformation.NetworkInterface.GetAllNetworkInterfaces(). Однако я не знаю замены .NET для GetBestInterface. - person Rory MacLeod; 02.03.2013