天天看點

windows下自動切換并連接配接wifi熱點

這段時間做的一個項目,需要測試産品上wifi子產品的功能。測試方式:該wifi子產品作為AP熱點,筆記本連接配接這個熱點,然後ping外網,ping得通就表示功能OK。廢話不多說,進入正題。

windows初次連接配接某個wifi熱點的過程中,有一個很關鍵的步驟:生成wifi配置檔案(下面簡稱profile),當然,這一步是windows根據你的wifi熱點自動生成的,是以想要讓電腦自動連接配接一個未連接配接過的熱點,軟體必須拼接出一個profile檔案,并添加到windows的wifi清單中。profile一般格式如下圖:

windows下自動切換并連接配接wifi熱點

不同的wifi熱點profile不太一樣,上圖是我的測試産品熱點的profile,畢竟是量産産品,數量比較大,設定為不加密是為了友善修改它,隻需要修改熱點名就可以。

profile檔案已經有了,需要用netsh工具添加到windows的wifi清單裡面去,比如我的profile存放在D盤,用下面的指令:

netsh wlan add profile filename="D:\\\wifitest.xml"  #這裡用絕對路徑,檔案名跟檔案裡的name要一樣
           

設定參數:配置檔案名,熱點名以及密碼

netsh wlan set profileparameter name=wifitest SSIDname="test_ap" keyMaterial=12345678
           

連接配接wifi熱點:

netsh wlan connect name=wifitest ssid="test_ap"
           

ping外網:

ping  www.baidu.com
           

手動操作到這裡就結束了,但身為一介碼農,自動化測試才是你的價值展現。

VC++下自動連接配接wifi熱點

根據上面的描述,總結幾個關鍵的步驟:

  1. 根據已有的配置檔案,修改wifi熱點名(有必要的話密碼也修改,我們的測試産品密碼用的都是同樣的);
  2. 将配置檔案添加到windows的wifi清單;
  3. 設定配置檔案參數;
  4. 連接配接熱點;
  5. ping外網

思路:wifi的ssid作為輸入,修改xml檔案中的熱點名,把上面用到的netsh指令寫成bat腳本,然後在程式裡修改bat腳本并執行,代碼實作如下:(string和wstring互相轉換的接口是從網上找的)

// An highlighted block
#include "tinyxml.h"
#include <wlanapi.h>
#include <windows.h>
#include <iostream>
#include <fstream>

//wstring to string
std::string ConvertWStringToAnsi(std::wstring wstr)
{
	std::string result;
	int len = WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), NULL, 0, NULL, NULL);
	if( len <= 0 )
		return result;
 
	char* buffer = new char[len + 1];
	if(buffer == NULL )
		return result;
 
	WideCharToMultiByte(CP_ACP, 0, wstr.c_str(), wstr.size(), buffer, len, NULL, NULL);
	buffer[len] = '\0';
	result.append(buffer);
	delete[] buffer;
 
	return result;
}

//string to wstring
std::wstring ConvertAnsiToWString(std::string str)
{
	std::wstring result;
 
	int len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), NULL, 0);
	if( len < 0 )
		return result;
 
	wchar_t* buffer = new wchar_t[len + 1];
	if( buffer == NULL )
		return result;
 
	MultiByteToWideChar(CP_ACP, 0, str.c_str(), str.size(), buffer, len);
 
	buffer[len] = '\0';
	result.append(buffer);
	delete[] buffer;
 
	return result;
}

bool Modify_BatFile(std::wstring path, std::string ssid)
{
	ifstream ifile;
	
	std::string PathTmp = ConvertWStringToAnsi(path);
	ifile.open(PathTmp.c_str(), ios::in);
	if(!ifile.is_open())
	{
		return false;
	}

	std::string bakfile = PathTmp + ".bak";
	ofstream ofile(bakfile.c_str());
	if(!ofile)
	{
		return false;
	}
	
	char strline[1024] = {0};
	while(ifile.good() && !ifile.eof())
	{
		memset(strline, 0x00, sizeof(strline));
		ifile.getline(strline, 1024);
		
		if(strstr(strline, "set SSID="))
		{
			ofile << "set SSID=" << ssid << std::endl;
			continue;
		}
		ofile << strline << std::endl;
	}

	ifile.close();
	ofile.close();
	
	if(!DeleteFile(path.c_str()))
	{
		return false;
	}
	if(rename(bakfile.c_str(), PathTmp.c_str()))
	{
		return false;
	}

	return true;
}
//修改bat腳本接口
bool Modify_Wifi_Profile(std::string ssid)
{
	TiXmlDocument doc;
	
	std::string filename = "D:\\wifitest.xml";
	if(!doc.LoadFile(filename.c_str()))
	{
		return false;
	}

	TiXmlElement *Root = doc.RootElement();
	TiXmlNode *SSIDConfig = Root->FirstChild("SSIDConfig");
	if(!SSIDConfig)//can't find SSIDConfig
	{
		return false;
	}
	
	TiXmlNode *SSID = SSIDConfig->FirstChild("SSID");//因為我們需要的ssid熱點名:name是SSID的子節點,是以先找父節點
	if(!SSID)//can't find SSID
	{
		return false;
	}

	TiXmlNode *name = SSID->FirstChild("name");//找到ssid熱點名,修改為傳入的ssid
	if(!name)
	{
		return false;
	}
	TiXmlText nameText(ssid.c_str());
	TiXmlNode *name_tmp = name->FirstChild();
	name->ReplaceChild(name_tmp, nameText);

	doc.SaveFile("D:\\wifitest.xml");

	std::wstring pingPath = L"D:\\test.bat";
	if(false == Modify_BatFile(pingPath, ssid))
	{
		return false;
	}
	
	int ret = ShellExecute(NULL, L"open", pingPath.c_str(), NULL, NULL, SW_SHOWNORMAL);
	if(ret < 32)//if shellexcute failed, the return value would be < 32,.Why? please Baidu.
	{
		return false;
	}

	return true;
}
           

bat腳本,裡面有部分參考了Roger0212大神的代碼,原文連結:https://blog.csdn.net/lile777/article/details/78686727

@echo off
title wifi測試
echo.
echo.

set SSID=test_ap
netsh wlan delete profile name="wifitest"	::因為我在測試過程中用的同一個profile,是以在下次測試之前需要先把原來的删掉,再重新添加
netsh wlan add profile filename="D:\\wifitest.xml"
netsh wlan set profileparameter name=wifitest SSIDname="%SSID%" keyMaterial=12345678
netsh wlan connect name=wifitest ssid="%SSID%"

::下面這部分參考了大神:Roger0212的代碼,原文連結https://blog.csdn.net/lile777/article/details/78686727 
ping -n 2 www.baidu.com > %temp%\1.ping    
findstr "TTL" %temp%\1.ping > nul
if %errorlevel%==0 (echo     √ 外網正常) else (echo     × 外網不通)         
if exist %temp%\*.ping del %temp%\*.ping

echo.
echo.
pause
           

上面就是本次的分享了,有什麼不合理的請及時指正,謝謝。

繼續閱讀