使用ManagedWifi连接无线网络

岳杜吟
2023-12-01


windows vistawindows XP SP2以后的版本,微软支持使用Native wifi API来连接和管理无线网络。不过官方文档中有句话:Ad hoc mode might not be available in future versions of Windows. Starting with Windows 8.1 and Windows Server 2012 R2, use Wi-Fi Direct instead.高级模式将不被支持。从Windows 8.1Windows Server 2012 R2开始,请使用Wi-Fi Direct替代。这个我们暂时先不用理会。

Native wifi API可以的下载地址:http://download.csdn.net/detail/libby1984/9529224


下面是代码:

判断电脑是否连接上了网络:

        [DllImport("wininet")]
        private extern static bool InternetGetConnectedState(out int connectionDescription, int reservedValue);

        /// <summary>
        /// 检测本机是否联网
        /// </summary>
        /// <returns></returns>
        public static bool IsConnectedInternet()
        {
            int i = 0;
            if (InternetGetConnectedState(out i, 0))
            {
                //已联网
                return true;
            }
            else
            {
                //未联网
                return false;
            }
        }

扫描无线网络,首先实例化一个WlanClient的实例,遍历该实例中所有的WlanInterface。每一个WlanInterface 就是一个无线网络连接。然后遍历每个连接下搜索到的所有无线网络。如果WlanInterface的InterfaceState属性值为Connected,那么就表示该无线网络连接是当前连接的连接,如果想具体知道连接的是哪个无线网络,可以查看WlanInterface实例的CurrentConnection属性。下面代码中的WIFISSID类是记录netwoek参数的类,可以根据需要自己定义。

	/// <summary>  
        /// 枚举所有无线设备接收到的SSID  
        /// </summary>  
        private List<WIFISSID> ScanSSID()
        {
            WlanClient client = new WlanClient();
            List<WIFISSID> wifiList = new List<WIFISSID>();
            string conectedNetworkName = string.Empty;
            foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
            {
                List<string> profileNames = new List<string>();
                // Lists all networks with WEP security  
                Wlan.WlanAvailableNetwork[] networks = wlanIface.GetAvailableNetworkList(0);
                foreach (Wlan.WlanAvailableNetwork network in networks)
                {
                    if (wlanIface.InterfaceState == Wlan.WlanInterfaceState.Connected && wlanIface.CurrentConnection.isState == Wlan.WlanInterfaceState.Connected)
                    {
                        conectedNetworkName = wlanIface.CurrentConnection.profileName;
                    }
                    
                    WIFISSID targetSSID = new WIFISSID();
                    if (network.networkConnectable)
                    {
                        targetSSID.SSID = network.dot11Ssid;
                        if (string.IsNullOrEmpty(network.profileName))
                        {
                            targetSSID.profileNames = GetStringForSSID(network.dot11Ssid);
                        }
                        else
                        {
                            targetSSID.profileNames = network.profileName;
                        }


                        if (!profileNames.Contains(targetSSID.profileNames))
                        {
                            profileNames.Add(targetSSID.profileNames);
                            targetSSID.wlanInterface = wlanIface;
                            targetSSID.wlanSignalQuality = (int)network.wlanSignalQuality;
                            targetSSID.dot11DefaultAuthAlgorithm = network.dot11DefaultAuthAlgorithm;
                            targetSSID.dot11DefaultCipherAlgorithm = network.dot11DefaultCipherAlgorithm.ToString();
                            targetSSID.securityEnabled = network.securityEnabled;
                            wifiList.Add(targetSSID);
                            if (!string.IsNullOrEmpty(conectedNetworkName) && conectedNetworkName.Equals(network.profileName))
                            {
                                targetSSID.connected = true;
                            }
                            else
                            {
                                targetSSID.connected = false;
                            }
                        }
                    }
                }
            }

            return wifiList;
        }

public class WIFISSID
{
        public string profileNames;
        public Wlan.Dot11Ssid SSID;
        public NativeWifi.Wlan.Dot11AuthAlgorithm dot11DefaultAuthAlgorithm;
        public string dot11DefaultCipherAlgorithm = "";
        public bool networkConnectable = true;
        public string wlanNotConnectableReason = "";
        public int wlanSignalQuality = 0;
        public WlanClient.WlanInterface wlanInterface = null;
        public bool securityEnabled;
        public bool connected = false;
} 


寻找当前连接的网络:

	public static string GetCurrentConnection()
        {
            WlanClient client = new WlanClient();
            foreach (WlanClient.WlanInterface wlanIface in client.Interfaces)
            {
                Wlan.WlanAvailableNetwork[] networks = wlanIface.GetAvailableNetworkList(0);
                foreach (Wlan.WlanAvailableNetwork network in networks)
                {
                    if (wlanIface.InterfaceState == Wlan.WlanInterfaceState.Connected && wlanIface.CurrentConnection.isState == Wlan.WlanInterfaceState.Connected)
                    {
                        return wlanIface.CurrentConnection.profileName;
                    }
                }
            }

            return string.Empty;
        }

连接到无线网络。连接到无线网络需要传无线网络配置文件,这个配置文件是一个XML,根据不同的网络配置文件中的参数不同。

下面的例子中的infoTB是界面上的一个TextBlock控件,用来显示提示信息,而Loger类是一个自定义类。各位可以根据自己的需要对显示提示信息的部分进行修改。

	/// <summary> 
        /// 连接到无线网络
        /// </summary> 
        /// <param name="ssid"></param> 
        public void ConnectToSSID(WIFISSID ssid, string key) 
        { 
            try {
                String auth = string.Empty;
                String cipher = string.Empty; 
                bool isNoKey = false;
                String keytype = string.Empty; 
                switch (ssid.dot11DefaultAuthAlgorithm) 
                { 
                    case Wlan.Dot11AuthAlgorithm.IEEE80211_Open: 
                        auth = "open"; break; 
                    //case Wlan.Dot11AuthAlgorithm.IEEE80211_SharedKey: 
                    // 'not implemented yet; 
                    //break; 
                    case Wlan.Dot11AuthAlgorithm.RSNA: 
                        auth = "WPA2PSK"; break; 
                    case Wlan.Dot11AuthAlgorithm.RSNA_PSK: 
                        auth = "WPA2PSK"; break; 
                    case Wlan.Dot11AuthAlgorithm.WPA: 
                        auth = "WPAPSK"; break; 
                    case Wlan.Dot11AuthAlgorithm.WPA_None: 
                        auth = "WPAPSK"; break; 
                    case Wlan.Dot11AuthAlgorithm.WPA_PSK: 
                        auth = "WPAPSK"; break; 
                } 
                
                switch (ssid.dot11DefaultCipherAlgorithm) 
                { 
                    case Wlan.Dot11CipherAlgorithm.CCMP: 
                        cipher = "AES"; 
                        keytype = "passPhrase"; 
                        break; 
                    case Wlan.Dot11CipherAlgorithm.TKIP: 
                        cipher = "TKIP"; 
                        keytype = "passPhrase";
                        break; 
                    case Wlan.Dot11CipherAlgorithm.None: 
                        cipher = "none"; keytype = ""; 
                        isNoKey = true; 
                        break; 
                    case Wlan.Dot11CipherAlgorithm.WEP: 
                        cipher = "WEP"; 
                        keytype = "networkKey"; 
                        break; 
                    case Wlan.Dot11CipherAlgorithm.WEP40: 
                        cipher = "WEP"; 
                        keytype = "networkKey"; 
                        break; 
                    case Wlan.Dot11CipherAlgorithm.WEP104:
                        cipher = "WEP"; 
                        keytype = "networkKey"; 
                        break;
                }

                if (isNoKey && !string.IsNullOrEmpty(key))
                {
                    infoTB.Text = "无法连接网络!";
                    Loger.WriteLog("无法连接网络",
                        "SSID:" + this.ssid.SSID + "\r\n"
                        + "Dot11AuthAlgorithm:" + ssid.dot11DefaultAuthAlgorithm + "\r\n"
                        + "Dot11CipherAlgorithm:" + ssid.dot11DefaultAuthAlgorithm.ToString());
                    return;
                }
                else if (!isNoKey && string.IsNullOrEmpty(key))
                {
                    infoTB.Text = "无法连接网络!";
                    Loger.WriteLog("无法连接网络",
                        "SSID:" + this.ssid.SSID + "\r\n"
                        + "Dot11AuthAlgorithm:" + ssid.dot11DefaultAuthAlgorithm + "\r\n"
                        + "Dot11CipherAlgorithm:" + ssid.dot11DefaultAuthAlgorithm.ToString());
                    return;
                }
                else
                {
                    string profileName = ssid.profileNames; // this is also the SSID 
                    string mac = StringToHex(profileName);
                    string profileXml = string.Empty;
                    if (!string.IsNullOrEmpty(key))
                    {
                        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><connectionMode>auto</connectionMode><autoSwitch>false</autoSwitch><MSM><security><authEncryption><authentication>{2}</authentication><encryption>{3}</encryption><useOneX>false</useOneX></authEncryption><sharedKey><keyType>{4}</keyType><protected>false</protected><keyMaterial>{5}</keyMaterial></sharedKey><keyIndex>0</keyIndex></security></MSM></WLANProfile>",
                            profileName, mac, auth, cipher, keytype, key); 
                    }
                    else
                    {
                        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><connectionMode>auto</connectionMode><autoSwitch>false</autoSwitch><MSM><security><authEncryption><authentication>{2}</authentication><encryption>{3}</encryption><useOneX>false</useOneX></authEncryption></security></MSM></WLANProfile>",
                            profileName, mac, auth, cipher, keytype); 
                    }

                    ssid.wlanInterface.SetProfile(Wlan.WlanProfileFlags.AllUser, profileXml, true);
                    //ssid.wlanInterface.Connect(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, ssid.profileNames);
                    bool success = ssid.wlanInterface.ConnectSynchronously(Wlan.WlanConnectionMode.Profile, Wlan.Dot11BssType.Any, profileName, 15000);
                    if (!success)
                    {
                        infoTB.Text = "连接网络失败!";
                        Loger.WriteLog("连接网络失败",
                            "SSID:" + this.ssid.SSID + "\r\n"
                            + "Dot11AuthAlgorithm:" + ssid.dot11DefaultAuthAlgorithm + "\r\n"
                            + "Dot11CipherAlgorithm:" + ssid.dot11DefaultAuthAlgorithm.ToString() + "\r\n");
                        return;
                    }
                } 
            } 
            catch (Exception e) 
            {
                infoTB.Text = "无法连接网络!" + e.Message;
                Loger.WriteLog("无法连接网络",
                    "SSID:" + this.ssid.SSID + "\r\n"
                    + "Dot11AuthAlgorithm:" + ssid.dot11DefaultAuthAlgorithm + "\r\n"
                    + "Dot11CipherAlgorithm:" + ssid.dot11DefaultAuthAlgorithm.ToString() + "\r\n"
                    + e.Message);
                return;
            } 
        } 

如果想要了解连接无线网络过程中的细节,可以注册WlanInterface的WlanConnectionNotification事件。该事件会对当连接的连接状态进行通知,下面是简单的通知事件的实现,根据通知的内容在界面上显示提示信息:
	private void WlanInterface_WlanConnectionNotification(Wlan.WlanNotificationData notifyData, Wlan.WlanConnectionNotificationData connNotifyData)
        {
            try
            {
                this.Dispatcher.BeginInvoke(new Action(() =>
                {
                    if (!this.ssid.profileNames.Equals(connNotifyData.profileName))  // 是否是当前SSID的通知
                    {
                        return;
                    }

                    if (notifyData.notificationSource == Wlan.WlanNotificationSource.ACM)
                    {
                        
                        int notificationCode = (int)notifyData.NotificationCode;
                        switch (notificationCode)
                        {
                            case (int)Wlan.WlanNotificationCodeAcm.ConnectionStart:
                                Loger.WriteLog("开始连接无线网络" + this.ssid.profileNames);
                                infoTB.Text = "开始连接无线网络......";
                                break;
                            case (int)Wlan.WlanNotificationCodeAcm.ConnectionComplete:
                                Loger.WriteLog("连接无线网络成功" + this.ssid.profileNames);
                                infoTB.Text = "连接无线网络成功!";
                                this.DialogResult = true;
                                break;
                            case (int)Wlan.WlanNotificationCodeAcm.Disconnecting:
                                Loger.WriteLog("正在断开无线网络连接" + this.ssid.profileNames);
                                infoTB.Text = "正在断开无线网络连接......";
                                break;
                            case (int)Wlan.WlanNotificationCodeAcm.Disconnected:
                                Loger.WriteLog("已经断开无线网络连接" + this.ssid.profileNames);
                                infoTB.Text = "已经断开无线网络连接!";
                                this.DialogResult = true;
                                break;
                        }
                    }
                }));
            }
            catch (Exception e)
            {
                Loger.WriteLog(e.Message);
            }
        }



 类似资料: