Windows 10 操作系統下利用USB無限網卡創建虛擬WirelessNetwork 類的封裝

最近因爲公司的業務要求,在沒有網絡的情況下,沒有路由器支持的情況下,需要組建一個小局域網,可以同時支持多個終端的相互之間的通信,這裏的解決方案如下。


一、硬件要求:任意支持軟AP的無限網卡,具體是否支持請輸入命令行如下查看,如圖(一):


圖(一)

根據上圖,包含 C:\Windows\system32\DRIVERS\vwifibus.sys即可支持軟AP。

二、熟悉命令

1.設置並允許虛擬無線網路;

命令:netsh 命令符下輸入 wlan set hostednetwork mode = allow ssid=無線名稱 key=無線密碼(8位數)

返回結果:承載網絡模式已設置爲允許。
已成功更改承載網絡的 SSID。
已成功更改託管網絡的用戶密鑰密碼。


2.顯示設置的虛擬網絡信息;

命令:netsh 命令符下輸入 wlan show hostednetwork

返回結果:承載網絡設置
-----------------------
    模式                   : 已啓用
    SSID 名稱              :“無線名稱”
    最多客戶端數  : 32
    身份驗證         : WPA2 - 個人
    密碼                 : CCMP


承載網絡狀態
---------------------
    狀態                 : 未啓動


netsh>


3.啓動設置的無線網絡

命令:netsh 命令符下輸入 wlan start hostednetwork


4.停止設置的無線網絡

命令:netsh 命令符下輸入 wlan stop hostednetwork


5.禁止設置的無線網絡

命令:命令:netsh 命令符下輸入 wlan set hostednetwork mode=disallow

返回結果:承載網絡模式已設置爲禁止。


三、對應封裝的C#類,代碼如下:

public class VWirelessNetworkManager
    {
        private bool isEnableDynamicKey = false;
        private string cleartextKey = null;


        public event EventHandler<VWirelessNetworkEventArgs> VWirelessStarted;
        public event EventHandler<VWirelessNetworkEventArgs> VWirelessStopped;
        public event EventHandler<VWirelessNetworkEventArgs> VWirelessSetted;

        private static readonly Process currentProcess = null;
        private static Process CurrentProcess { get; }
        private static bool isRunNetsh = true;
        private static bool isExitNetsh = false;

        /// <summary>
        /// 虛擬無線網絡信息
        /// </summary>
        public VWirelessNetwork VWirelessNetworkInfo
        {
            get { return this.GetVWirelessNetwork(); }
        }

        static VWirelessNetworkManager()
        {
            currentProcess = new Process();
            currentProcess.StartInfo = new ProcessStartInfo()
            {
                RedirectStandardInput = true,
                RedirectStandardOutput = true,
                RedirectStandardError = true,
                UseShellExecute = false,
                CreateNoWindow = true,
                //FileName = "netsh"
                FileName = "netsh"
            };
            currentProcess.Start();
        }

        private bool RunNetsh()
        {
            if (!isRunNetsh)
            {
                isRunNetsh = true;
                isExitNetsh = false;
                currentProcess.Start();
            }
            return isRunNetsh;
        }

        private bool ExitNetsh()
        {
            if (!isExitNetsh)
            {
                currentProcess.StandardInput.WriteLine("exit");
                isRunNetsh = false;
                isExitNetsh = true;
            }
            return isExitNetsh;
        }

        public void SetVWirelessInfo(string sSID)
        {
            string encryptPlus;
            string key = GetDynamicVWirelessKey(sSID, out encryptPlus);
            SetVWirelessInfo(sSID, key, true);
        }

        public void SetVWirelessInfo(string sSID, string key)
        {
            SetVWirelessInfo(sSID, key, false);
        }

        public void SetVWirelessInfo(string sSID, string key, bool isEnableDynamicKey)
        {
            this.cleartextKey = key;
            this.isEnableDynamicKey = isEnableDynamicKey;
            RunNetsh();
            currentProcess.StandardInput.AutoFlush = true;
            currentProcess.StandardInput.WriteLine(string.Format("wlan set hostednetwork mode=allow ssid={0} key={1}", sSID, key));
            ExitNetsh();
            VWirelessNetworkEventArgs e = new PlatForm.VWirelessNetworkEventArgs();
            e.CommandExecutedResult = currentProcess.StandardOutput.ReadToEnd();
            e.VWirelessNetworkShowInfo = GetVWirelessNetwork();
            OnVWirelessSetted(e);
        }

        public void StartVWirelessNet()
        {
            RunNetsh();
            currentProcess.StandardInput.AutoFlush = true;
            currentProcess.StandardInput.WriteLine("wlan start hostednetwork");
            ExitNetsh();
            VWirelessNetworkEventArgs e = new PlatForm.VWirelessNetworkEventArgs();
            e.CommandExecutedResult = currentProcess.StandardOutput.ReadToEnd();
            e.VWirelessNetworkShowInfo = GetVWirelessNetwork();
            e.IPAddress = GetIpAddress();
            OnVWirelessStarted(e);
        }

        public void StopVWirelessNet()
        {
            RunNetsh();
            currentProcess.StandardInput.AutoFlush = true;
            currentProcess.StandardInput.WriteLine("wlan stop hostednetwork");
            ExitNetsh();
            VWirelessNetworkEventArgs e = new PlatForm.VWirelessNetworkEventArgs();
            e.CommandExecutedResult = currentProcess.StandardOutput.ReadToEnd();
            e.VWirelessNetworkShowInfo = GetVWirelessNetwork();
            OnVWirelessStopped(e);
        }

        public void DisallowVWirelessNet()
        {
            RunNetsh();
            currentProcess.StandardInput.AutoFlush = true;
            currentProcess.StandardInput.WriteLine("wlan set hostednetwork mode=disallow");
            ExitNetsh();
            VWirelessNetworkEventArgs e = new PlatForm.VWirelessNetworkEventArgs();
            e.CommandExecutedResult = currentProcess.StandardOutput.ReadToEnd();
            e.VWirelessNetworkShowInfo = GetVWirelessNetwork();
        }


        protected virtual VWirelessNetwork GetVWirelessNetwork()
        {
            RunNetsh();
            currentProcess.StandardInput.AutoFlush = true;
            currentProcess.StandardInput.WriteLine("wlan show hostednetwork");
            ExitNetsh();
            VWirelessNetwork vWNInfo = new VWirelessNetwork();
            vWNInfo.IsEnableDynamicKey = isEnableDynamicKey;
            vWNInfo.RawVWirelessNetworkShowInfo = currentProcess.StandardOutput.ReadToEnd();
            string[] kvpItems = vWNInfo.RawVWirelessNetworkShowInfo.Split(new char[] { '\r', '\n' });
            if (kvpItems.Length > 14)
            {
                vWNInfo.BearerNetworkSettings = new PlatForm.BearerNetworkSettings()
                {
                    Mode = kvpItems[6].Split(':')[1].Trim(),
                    SSID = kvpItems[8].Split(':')[1].Trim().Trim(new char[] { '“', '”' }),
                    MaxClientQuantity = int.Parse(kvpItems[10].Split(':')[1]),
                    Authentication = kvpItems[12].Split(':')[1].Trim(),
                    Key = this.isEnableDynamicKey ? kvpItems[14].Split(':')[1].Trim() : this.cleartextKey
                };
                vWNInfo.BearerNetworkStatus = new BearerNetworkStatus();
                string status = kvpItems[22].Split(':')[1].Trim();
                vWNInfo.BearerNetworkStatus.Status = status;
                if (status == "已啓動")
                {
                    vWNInfo.BearerNetworkStatus.BSSID = kvpItems[24].Substring(28, 17);
                    vWNInfo.BearerNetworkStatus.WirelessType = kvpItems[26].Split(':')[1].Trim();
                    vWNInfo.BearerNetworkStatus.Channels = int.Parse(kvpItems[28].Split(':')[1]);
                    int clientQuantity = int.Parse(kvpItems[30].Split(':')[1]);
                    vWNInfo.BearerNetworkStatus.ClientQuantity = clientQuantity;


                    if (clientQuantity > 0)
                    {
                        for (int i = 1; i <= clientQuantity; i++)
                        {
                            vWNInfo.BearerNetworkStatus.Clients.Add(kvpItems[30 + i * 2].TrimStart().Substring(0, 17));
                        }
                    }
                }
            }
            return vWNInfo;
        }

        public string GetIpAddress()
        {
            string ipV4Address = null;
            //獲取虛擬無限網絡的IPV4地址
            NetworkInterface vNetwork = NetworkInterface.GetAllNetworkInterfaces().FirstOrDefault(w => w.Description == "Microsoft Hosted Network Virtual Adapter" && w.NetworkInterfaceType == NetworkInterfaceType.Wireless80211);
            UnicastIPAddressInformationCollection ipCollection = vNetwork.GetIPProperties().UnicastAddresses;
            if (ipCollection.Count > 1)
            {
                ipV4Address = ipCollection[1].Address.ToString();
            }
            else
            {
                ipV4Address = ipCollection[0].Address.ToString();
            }
            return ipV4Address;
        }

        protected virtual void OnVWirelessStarted(VWirelessNetworkEventArgs e)
        {
            if (VWirelessStarted != null)
            {
                VWirelessStarted(this, e);
            }
        }

        protected virtual void OnVWirelessStopped(VWirelessNetworkEventArgs e)
        {
            if (VWirelessStopped != null)
            {
                VWirelessStopped(this, e);
            }
        }

        protected virtual void OnVWirelessSetted(VWirelessNetworkEventArgs e)
        {
            if (VWirelessSetted != null)
            {
                VWirelessSetted(this, e);
            }
        }

        private static string GetDynamicVWirelessKey(string sSID, out string encryptPlus)
        {
            string encrypedSSID = GetHashedString32(sSID); ;
            string head = null;
            string tail = null;
            encryptPlus = Guid.NewGuid().ToString();
            char[] chars = encryptPlus.ToCharArray();
            for (int i = 0; i < chars.Length; i++)
            {
                if (i % 2 == 0)
                {
                    head += chars[i];
                }
                else
                {
                    tail += chars[i];
                }
            }
            string waitingEncryptString2 = head + encrypedSSID + tail;
            return GetHashedString32(waitingEncryptString2);
        }

        private static string GetHashedString32(string waitingEncryptString)
        {
            string encrypedString = null;
            byte[] buff = Encoding.UTF8.GetBytes(waitingEncryptString);
            MD5CryptoServiceProvider md5 = new MD5CryptoServiceProvider();
            byte[] encryptedBuff = md5.ComputeHash(buff);
            foreach (byte b in encryptedBuff)
            {
                encrypedString += b.ToString("X2");
            }
            return encrypedString;
        }
    }

 /// <summary>
    /// 虛擬無線網絡事件參數
    /// </summary>
    public class VWirelessNetworkEventArgs : EventArgs
    {
        /// <summary>
        /// 命令執行後的結果
        /// </summary>
        public string CommandExecutedResult { get; set; }
        /// <summary>
        /// 虛擬無限網絡的IP地址
        /// </summary>
        public string IPAddress { get; set; }
        /// <summary>
        /// 顯示虛擬無線網絡信息
        /// </summary>
        public VWirelessNetwork VWirelessNetworkShowInfo { get; set; }
    }
    /// <summary>
    /// 虛擬無線網絡信息
    /// </summary>
    public class VWirelessNetwork
    {
        /// <summary>
        /// 顯示虛擬無線網絡原始信息
        /// </summary>
        public string RawVWirelessNetworkShowInfo { get; set; }
        /// <summary>
        /// 是否啓用虛擬無限網絡動態生成密碼
        /// </summary>
        public bool IsEnableDynamicKey { get; set; }
        /// <summary>
        /// 承載虛擬無線網絡設置
        /// </summary>
        public BearerNetworkSettings BearerNetworkSettings { get; set; }
        /// <summary>
        /// 承載虛擬無線網絡狀態
        /// </summary>
        public BearerNetworkStatus BearerNetworkStatus { get; set; }
    }

    /// <summary>
    /// 承載網絡設置
    /// </summary>
    public class BearerNetworkSettings
    {
        /// <summary>
        /// 模式
        /// </summary>
        public string Mode { get; set; }
        /// <summary>
        /// SSID 名稱
        /// </summary>
        public string SSID { get; set; }
        /// <summary>
        /// 最多客戶端數
        /// </summary>
        public int MaxClientQuantity { get; set; }
        /// <summary>
        /// 身份驗證
        /// </summary>
        public string Authentication { get; set; }
        /// <summary>
        /// 密碼
        /// </summary>
        public string Key { get; set; }
    }

    /// <summary>
    /// 承載網絡狀態
    /// </summary>
    public class BearerNetworkStatus
    {
        private IList<string> clients = new List<string>();

        /// <summary>
        /// 狀態
        /// </summary>
        public string Status { get; set; }
        /// <summary>
        /// BSSID
        /// </summary>
        public string BSSID { get; set; }
        /// <summary>
        /// 無線電類型
        /// </summary>
        public string WirelessType { get; set; }
        /// <summary>
        /// 頻道
        /// </summary>
        public int Channels { get; set; }
        /// <summary>
        /// 客戶端數
        /// </summary>
        public int ClientQuantity { get; set; }
        /// <summary>
        /// 客戶端MAC地址列表
        /// </summary>
        public IList<string> Clients { get { return clients; } }
    } 

四、測試代碼如下:

VWirelessNetworkManager vwifi = null;
  vwifi = new VWirelessNetworkManager();
            vwifi.VWirelessSetted += Vwifi_VWirelessSetted;
            vwifi.VWirelessStarted += Vwifi_VWirelessStarted;
            vwifi.VWirelessStopped += Vwifi_VWirelessStopped;

 /// <summary>
        /// 窗口加載事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void FrmShowNetInfo_Load(object sender, EventArgs e)
        {
            //this.lstboxMessage.Items.Add("消息:正在啓動應用程序!");
            RunatVWirelessNetwork();
        }

        private void RunatVWirelessNetwork()
        {
            // this.lstboxMessage.Items.Add("消息:正在檢測是否安裝USB版本的無限網卡!");
            if (CheckWirelessCard())
            {
                // this.lstboxMessage.Items.Add("消息:檢測已經安裝USB版本的無限網卡!");
                if (GlobalConfig.AppSettings.VWirelessNetwork.IsEnableDynamicKey)
                {
                    //this.lstboxMessage.Items.Add("消息:動態生成密碼功能已開啓,以規則運算方式並創建虛擬無限網絡!");
                    vwifi.SetVWirelessInfo(string.Format("SmTR-{0}", DateTime.Now.ToString("HHmmssfffffff")));
                }
                else
                {
                    //this.lstboxMessage.Items.Add("消息:動態生成密碼功能未開啓,以明文密碼方式並創建虛擬無限網絡!");
                    vwifi.SetVWirelessInfo(string.Format("SmTR-{0}", DateTime.Now.ToString("HHmmssfffffff")), DateTime.Now.ToOADate().ToString());
                }
                //this.lstboxMessage.Items.Add("消息:正在啓動虛擬無限網絡!");
                vwifi.StartVWirelessNet();
            }
            else
            {
                Application.Exit();
            }

五、說明

最後測試部分的動態密碼的意思是提供不公開密碼的情況下,根據規則自動計算的,具體方法可以自己修改。

如有其他問題可以留言。




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章