【问题标题】:How do I get the available wifi APs and their signal strength in .net?如何在 .net 中获取可用的 wifi AP 及其信号强度?
【发布时间】:2010-10-04 12:55:05
【问题描述】:

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

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


这是我发现的几个类似的 stackoverflow 问题:

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

-Managing wireless network connection in C#

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

【问题讨论】:

    标签: c# .net networking mono wifi


    【解决方案1】:

    它是一个包装器项目,在http://www.codeplex.com/managedwifihttp://www.codeplex.com/managedwifi 处带有 c# 中的托管代码

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

    示例代码:

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

    【讨论】:

    • 谢谢你。但这对我不起作用。我正在使用 Windows 8.1,并且收到此异常“ManagedWifi.dll 中发生了‘System.ComponentModel.Win32Exception’类型的未处理异常”。有什么想法吗?
    • 尽管我在 Windows 10 和 VS 2015 上运行它,但我在其中一台机器上也遇到了这个错误。有什么线索吗?你能解决吗?
    【解决方案2】:

    如果平台是Windows10,可以使用Microsoft.Windows.SDK.Contracts包访问所有可用的wifi。

    首先,从 nuget 安装 Microsoft.Windows.SDK.Contracts 包。

    然后,您可以使用下一个代码获取 ssid 和信号强度。

    var adapters = await WiFiAdapter.FindAllAdaptersAsync();
    foreach (var adapter in adapters)
    {
        foreach (var network in adapter.NetworkReport.AvailableNetworks)
        {
            Console.WriteLine($"ssid: {network.Ssid}");
            Console.WriteLine($"signal strength: {network.SignalBars}");
        }
    }
    

    【讨论】:

      【解决方案3】:

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

      How to enumerate networks

      How to get signal strength

      【讨论】:

      • 信号强度不能在 windows XP 中使用。甚至不是每个 SP :(
      【解决方案4】:

      我正在从 C# 代码运行命令 netsh wlan show networks mode=bssid

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

      【讨论】:

        【解决方案5】:

        可能能够使用 WMI 查询来实现它。看看这个thread

        【讨论】:

          【解决方案6】:

          如果您正在使用 vista wmi 不适用于所有网络适配器,则 vista 的另一种替代方法是使用 netsh 命令。看看this codeproject article.

          【讨论】:

          • 感谢链接。 netsh 的问题是它没有给我我需要的所有信息(rssi),而且有时有点错误
          【解决方案7】:

          我找到了另一种方法,虽然它确实需要一些钱。

          rawether.net 提供了一个 .NET 库,可让您获取以太网驱动程序。

          【讨论】:

            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2013-09-20
            • 1970-01-01
            相关资源
            最近更新 更多