using System; using System.Collections.Generic; using System.Linq; using Vinno.FIS.Sonopost.Wireless.Win32; using Vinno.FIS.Sonopost.Wireless.Win32.Interop; using NotifCodeACM = Vinno.FIS.Sonopost.Wireless.Win32.Interop.WlanNotificationCodeAcm; using NotifCodeMSM = Vinno.FIS.Sonopost.Wireless.Win32.Interop.WlanNotificationCodeMsm; namespace Vinno.FIS.Sonopost.Wireless { public class Wifi { public event EventHandler ConnectionStatusChanged; private WlanClient _client; private WifiStatus _connectionStatus; private bool _isConnectionStatusSet = false; public bool NoWifiAvailable = false; public Wifi() { _client = new WlanClient(); NoWifiAvailable = _client.NoWifiAvailable; if (_client.NoWifiAvailable) return; foreach (var inte in _client.Interfaces) inte.WlanNotification += inte_WlanNotification; } /// /// Returns a list over all available access points /// public List GetAccessPoints(string id, bool wifiScan) { List accessPoints = new List(); if (_client.NoWifiAvailable) return accessPoints; var wlanInterface = _client.Interfaces.FirstOrDefault(c => c.NetworkInterface.Id == id); if (wlanInterface == null) { return accessPoints; } if (wifiScan) { wlanInterface.Scan();//会影响网络 } WlanAvailableNetwork[] rawNetworks = wlanInterface.GetAvailableNetworkList(WlanGetAvailableNetworkFlags.IncludeAllAdhocProfiles); List networks = new List(); // Remove network entries without profile name if one exist with a profile name. foreach (WlanAvailableNetwork network in rawNetworks) { //屏蔽特殊wifi if (CheckAvailableSSID(network.dot11Ssid) == false) { continue; } bool hasProfileName = !string.IsNullOrEmpty(network.profileName); bool anotherInstanceWithProfileExists = rawNetworks.Where(n => n.Equals(network) && !string.IsNullOrEmpty(n.profileName)).Any(); if (!anotherInstanceWithProfileExists || hasProfileName) networks.Add(network); } foreach (WlanAvailableNetwork network in networks) { accessPoints.Add(new AccessPoint(wlanInterface, network)); } return accessPoints; } /// /// Disconnect all wifi interfaces /// public void Disconnect() { if (_client.NoWifiAvailable) return; foreach (WlanInterface wlanIface in _client.Interfaces) { wlanIface.Disconnect(); } } public WifiStatus ConnectionStatus { get { if (!_isConnectionStatusSet) ConnectionStatus = GetForcedConnectionStatus(); return _connectionStatus; } private set { _isConnectionStatusSet = true; _connectionStatus = value; } } private void inte_WlanNotification(WlanNotificationData notifyData) { if (notifyData.notificationSource == WlanNotificationSource.ACM && (NotifCodeACM)notifyData.NotificationCode == NotifCodeACM.Disconnected) OnConnectionStatusChanged(WifiStatus.Disconnected); else if (notifyData.notificationSource == WlanNotificationSource.MSM && (NotifCodeMSM)notifyData.NotificationCode == NotifCodeMSM.Connected) OnConnectionStatusChanged(WifiStatus.Connected); } private void OnConnectionStatusChanged(WifiStatus newStatus) { ConnectionStatus = newStatus; if (ConnectionStatusChanged != null) ConnectionStatusChanged(this, new WifiStatusEventArgs(newStatus)); } // I don't like this method, it's slow, ugly and should be refactored ASAP. private WifiStatus GetForcedConnectionStatus() { if (NoWifiAvailable) return WifiStatus.Disconnected; bool connected = false; foreach (var i in _client.Interfaces) { try { var a = i.CurrentConnection; // Current connection throws an exception if disconnected. connected = true; } catch { } } if (connected) return WifiStatus.Connected; else return WifiStatus.Disconnected; } private bool CheckAvailableSSID(Dot11Ssid ssid) { var len = ssid.SSIDLength; var bytes = ssid.SSID; for (int i = 0; i < len; i++) { if (bytes[i] != 0) { return true; } } return false; } } public class WifiStatusEventArgs : EventArgs { public WifiStatus NewStatus { get; private set; } internal WifiStatusEventArgs(WifiStatus status) : base() { this.NewStatus = status; } } public enum WifiStatus { Disconnected, Connected } }