这段时间做的一个项目,需要测试产品上wifi模块的功能。测试方式:该wifi模块作为AP热点,笔记本连接这个热点,然后ping外网,ping得通就表示功能OK。废话不多说,进入正题。
windows初次连接某个wifi热点的过程中,有一个很关键的步骤:生成wifi配置文件(下面简称profile),当然,这一步是windows根据你的wifi热点自动生成的,所以想要让电脑自动连接一个未连接过的热点,软件必须拼接出一个profile文件,并添加到windows的wifi列表中。profile一般格式如下图:
不同的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热点
根据上面的描述,总结几个关键的步骤:
- 根据已有的配置文件,修改wifi热点名(有必要的话密码也修改,我们的测试产品密码用的都是同样的);
- 将配置文件添加到windows的wifi列表;
- 设置配置文件参数;
- 连接热点;
- 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
上面就是本次的分享了,有什么不合理的请及时指正,谢谢。