Pregunta

¿Hay alguna forma de acceder a todos los puntos de acceso WiFi y sus respectivos valores RSSI usando .NET? Sería realmente bueno si pudiera hacerlo sin usar código no administrado o incluso mejor si funcionara tanto en mono como en .NET.

Si es posible, solicitaría una muestra de código. Gracias


Aquí hay algunas preguntas similares de stackoverflow que encontré:

- Obtener SSID de la red inalámbrica a la que estoy conectado con C # .Net en Windows Vista

- Administrar la conexión de red inalámbrica en C #

- Obtenga BSSID (dirección MAC) de la red inalámbrica punto de acceso desde C #

¿Fue útil?

Solución

Es un proyecto envoltorio con código administrado en c # en http://www.codeplex.com/managedwifi

Es compatible con Windows Vista y XP SP2 (o versión posterior).

código de muestra:

using NativeWifi;
using System;
using System.Text;

namespace WifiExample
{
    class Program
    {
        /// <summary>
        /// Converts a 802.11 SSID to a string.
        /// </summary>
        static string GetStringForSSID(Wlan.Dot11Ssid ssid)
        {
            return Encoding.ASCII.GetString( ssid.SSID, 0, (int) ssid.SSIDLength );
        }

        static void Main( string[] args )
        {
            WlanClient client = new WlanClient();
            foreach ( WlanClient.WlanInterface wlanIface in client.Interfaces )
            {
                // Lists all networks with WEP security
                Wlan.WlanAvailableNetwork[] networks = wlanIface.GetAvailableNetworkList( 0 );
                foreach ( Wlan.WlanAvailableNetwork network in networks )
                {
                    if ( network.dot11DefaultCipherAlgorithm == Wlan.Dot11CipherAlgorithm.WEP )
                    {
                        Console.WriteLine( "Found WEP network with SSID {0}.", GetStringForSSID(network.dot11Ssid));
                    }
                }

                // Retrieves XML configurations of existing profiles.
                // This can assist you in constructing your own XML configuration
                // (that is, it will give you an example to follow).
                foreach ( Wlan.WlanProfileInfo profileInfo in wlanIface.GetProfiles() )
                {
                    string name = profileInfo.profileName; // this is typically the network's SSID

                    string xml = wlanIface.GetProfileXml( profileInfo.profileName );
                }

                // Connects to a known network with WEP security
                string profileName = "Cheesecake"; // this is also the SSID
                string mac = "52544131303235572D454137443638";
                string key = "hello";
                string profileXml = string.Format("<?xml version=\"1.0\"?><WLANProfile xmlns=\"http://www.microsoft.com/networking/WLAN/profile/v1\"><name>{0}</name><SSIDConfig><SSID><hex>{1}</hex><name>{0}</name></SSID></SSIDConfig><connectionType>ESS</connectionType><MSM><security><authEncryption><authentication>open</authentication><encryption>WEP</encryption><useOneX>false</useOneX></authEncryption><sharedKey><keyType>networkKey</keyType><protected>false</protected><keyMaterial>{2}</keyMaterial></sharedKey><keyIndex>0</keyIndex></security></MSM></WLANProfile>", profileName, mac, key);

                wlanIface.SetProfile( Wlan.WlanProfileFlags.AllUser, profileXml, true );
                wlanIface.Connect( Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, profileName );
            }
        }
    }
}

Otros consejos

Utilice las API de Wifi nativas, presentes en todos los sistemas Vista y XP SP3. XP SP2 tiene una API diferente con la que puede hacer lo mismo.

Cómo enumerar redes

Cómo obtener la intensidad de la señal

Lo estoy haciendo con un comando netsh wlan show networks mode=bssid del código C #.

using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using System.Threading.Tasks;

namespace ConsoleApp2
{
    class AccessPoint
    {
        public string SSID { get; set; }
        public string BSSID { get; set; }
        public byte Signal { get; set; }
    }

    class Program
    {
        private static async Task Main(string[] args)
        {
            var apList = await GetSignalOfNetworks();

            foreach (var ap in apList)
            {
                WriteLine($"{ap.BSSID} - {ap.Signal} - {ap.SSID}");
            }

            Console.ReadKey();
        }

        private static async Task<AccessPoint[]> GetSignalOfNetworks()
        {
            string result = await ExecuteProcessAsync(@"C:\Windows\System32\netsh.exe", "wlan show networks mode=bssid");

            return Regex.Split(result, @"[^B]SSID \d+").Skip(1).SelectMany(network => GetAccessPointFromNetwork(network)).ToArray();
        }

        private static AccessPoint[] GetAccessPointFromNetwork(string network)
        {
            string withoutLineBreaks = Regex.Replace(network, @"[\r\n]+", " ").Trim();
            string ssid = Regex.Replace(withoutLineBreaks, @"^:\s+(\S+).*$", "$1").Trim();

            return Regex.Split(withoutLineBreaks, @"\s{4}BSSID \d+").Skip(1).Select(ap => GetAccessPoint(ssid, ap)).ToArray();
        }

        private static AccessPoint GetAccessPoint(string ssid, string ap)
        {
            string withoutLineBreaks = Regex.Replace(ap, @"[\r\n]+", " ").Trim();
            string bssid = Regex.Replace(withoutLineBreaks, @"^:\s+([a-f0-9]{2}(:[a-f0-9]{2}){5}).*$", "$1").Trim();
            byte signal = byte.Parse(Regex.Replace(withoutLineBreaks, @"^.*(Signal|Sinal)\s+:\s+(\d+)%.*$", "$2").Trim());

            return new AccessPoint
            {
                SSID = ssid,
                BSSID = bssid,
                Signal = signal,
            };
        }

        private static async Task<string> ExecuteProcessAsync(string cmd, string args = null)
        {
            var process = new Process()
            {
                StartInfo = new ProcessStartInfo
                {
                    FileName = cmd,
                    Arguments = args,
                    RedirectStandardInput = false,
                    RedirectStandardOutput = true,
                    RedirectStandardError = true,
                    UseShellExecute = false,
                    CreateNoWindow = true,
                    StandardOutputEncoding = Encoding.UTF8,
                }
            };

            process.Start();

            string result = await process.StandardOutput.ReadToEndAsync();

            process.WaitForExit();

#if DEBUG
            if (result.Trim().Contains("The Wireless AutoConfig Service (wlansvc) is not running."))
            {
                return await GetFakeData();
            }
#endif

            return result;
        }

        private static async Task<string> GetFakeData()
        {
            var assembly = Assembly.GetExecutingAssembly();
            var resourceName = "ConsoleApp2.FakeData.txt";

            using (Stream stream = assembly.GetManifestResourceStream(resourceName))
            using (StreamReader reader = new StreamReader(stream))
            {
                return await reader.ReadToEndAsync();
            }
        }

        private static void WriteLine(string str)
        {
            Console.WriteLine(str);
        }
    }
}

Usted podría ser capaz de lograrlo utilizando consultas WMI. Eche un vistazo a este hilo .

Si está utilizando vista wmi no funciona con todos los adaptadores de red, otra alternativa para vista es utilizar el comando netsh. Eche un vistazo a este artículo del proyecto de código.

Encontré otra forma de hacerlo, aunque cuesta algo de dinero.

Hay una lib .NET disponible en rawether.net que le permite acceder a los controladores de ethernet.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top