C# 如何在 .net 中获取可用的 wifi AP 及其信号强度?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/496568/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-04 05:40:46  来源:igfitidea点击:

How do I get the available wifi APs and their signal strength in .net?

c#.netnetworkingmonowifi

提问by LDomagala

Is there any way to access all WiFi access points and their respective RSSI values using .NET? It would be really nice if I could do it without using unmanaged code or even better if it worked in mono as well as .NET.

有没有办法使用 .NET 访问所有 WiFi 接入点及其各自的 RSSI 值?如果我可以在不使用非托管代码的情况下做到这一点,那真是太好了,或者如果它可以在单声道和 .NET 中工作甚至更好。

If it is possible i would appriciate a code sample. Thanks

如果可能的话,我会提供一个代码示例。谢谢



Here are a few similiar stackoverflow questions i found:

以下是我发现的一些类似的 stackoverflow 问题:

-Get SSID of the wireless network I am connected to with C# .Net on Windows Vista

-获取我在 Windows Vista 上使用 C# .Net 连接到的无线网络的 SSID

-Managing wireless network connection in C#

-在 C# 中管理无线网络连接

-Get BSSID (MAC address) of wireless access point from C#

-从 C# 获取无线接入点的 BSSID(MAC 地址)

采纳答案by Jirapong

It is a wrapper project with managed code in c# at http://www.codeplex.com/managedwifi

它是一个包装项目,在http://www.codeplex.com/managedwifi 上使用c# 中的托管代码

It supports Windows Vista and XP SP2 (or later version).

它支持 Windows Vista 和 XP SP2(或更高版本)。

sample code:

示例代码:

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 );
            }
        }
    }
}

回答by andynormancx

You mightbe able to achieve it using WMI queries. Take a look at this thread.

可以使用 WMI 查询来实现它。看看这个线程

回答by Lee Treveil

If you are using vista wmi does not work with all network adapters, another alternative for vista is to use the netsh command. Have a look at this codeproject article.

如果您使用的是 vista wmi 不适用于所有网络适配器,则 vista 的另一种替代方法是使用 netsh 命令。看看这个 codeproject 文章。

回答by Nick

Use Native Wifi APIs, present on all Vista and XP SP3 systems. XP SP2 has a different API with which you can do the same thing.

使用所有 Vista 和 XP SP3 系统上都存在的原生 Wifi API。XP SP2 有一个不同的 API,您可以用它来做同样的事情。

How to enumerate networks

如何枚举网络

How to get signal strength

如何获得信号强度

回答by LDomagala

I found another way to do it, although it does cost some money.

我找到了另一种方法来做到这一点,虽然它确实要花一些钱。

There is a .NET lib available at rawether.netthat lets you get at the ethernet drivers.

rawether.net上有一个 .NET 库,可让您获得以太网驱动程序。

回答by lmcarreiro

I am doing it running a command netsh wlan show networks mode=bssidfrom C# code.

我正在运行netsh wlan show networks mode=bssid来自 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+).*$", "").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}).*$", "").Trim();
            byte signal = byte.Parse(Regex.Replace(withoutLineBreaks, @"^.*(Signal|Sinal)\s+:\s+(\d+)%.*$", "").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);
        }
    }
}