DT
14 квітня 2025 р. 15:38
Qt 6.8 MinGW - управление подключением WiFi из программы
Всем привет!
На Qt 6.8 MinGW пытаюсь сделать управление подключением WiFi из программы. Пока делаю поддержку Windows, но так же хочу в дальнейшем внедрить и поддержку Linux/MacOS.
Для управления пробрасываю команды в netsh и разбираю результат.
Пока загвоздка в разных локализациях системы, из-за чего или некорректно отображаются названия на русском языке (одни ??????????????), либо ничего не выдается из-за того, что не удается разобрать результат. Хотел бы библиотеку унифицировать.
Есть идеи?
Пока выглядит следующим образом:
wifimanager.h
- #ifndef WIFIMANAGER_H
- #define WIFIMANAGER_H
- #include <QtNetwork/QtNetwork>
- #include <QtCore>
- #include <QtGui>
- #include <QtWidgets>
- #include <list>
- /**
- * Open - открытая сеть без шифрования
- * Shared - устаревший режим WEP с общей аутентификацией
- * WPA-Personal - WPA с использованием PSK (Pre-Shared Key)
- * WPA-Enterprise - WPA с использованием RADIUS-сервера для аутентификации
- * WPA2-Personal - WPA2 с PSK (наиболее распространенный сейчас режим)
- * WPA2-Enterprise - WPA2 с RADIUS-сервером
- * WPA3-Personal - современный WPA3 с PSK
- * WPA3-Enterprise - WPA3 с RADIUS-сервером
- */
- typedef enum {
- AUTH_TYPE_UNKNOWN = 0,
- AUTH_TYPE_OPEN,
- AUTH_TYPE_SHARED,
- AUTH_TYPE_WPA_PERSONAL,
- AUTH_TYPE_WPA_ENTERPRISE,
- AUTH_TYPE_WPA2_PERSONAL,
- AUTH_TYPE_WPA2_ENTERPRISE,
- AUTH_TYPE_WPA3_PERSONAL,
- AUTH_TYPE_WPA3_ENTERPRISE,
- AUTH_TYPE_MAX
- } auth_type_t;
- typedef enum {
- WIFI_BAND_UNKNOWN = 0,
- WIFI_BAND_2_4_GHZ,
- WIFI_BAND_5_GHZ,
- WIFI_BAND_MAX
- } wifi_band_t;
- typedef enum {
- WIFI_STATE_DISCONNECTED = 0,
- WIFI_STATE_CONNECTED
- } wifi_state_t;
- typedef enum {
- INTERFACE_TYPE_PRIMARY = 0,
- INTERFACE_TYPE_SECONDARY
- } interface_type_t;
- /**
- * Name : Беспроводная сеть
- * Description : Intel(R) Wireless-AC 9560 160MHz
- * GUID : 082bf832-bae3-4933-a678-16e21e1dfb75
- * Physical address : 5c:87:9c:94:c2:76
- * Interface type : Primary
- * State : connected
- * SSID : tp-link
- * AP BSSID : 78:8c:b5:b7:27:a6
- * Band : 5 GHz
- * Channel : 48
- * Network type : Infrastructure
- * Radio type : 802.11ac
- * Authentication : WPA2-Personal
- * Cipher : CCMP
- * Connection mode : Profile
- * Receive rate (Mbps) : 780
- * Transmit rate (Mbps) : 780
- * Signal : 87%
- * Profile : tp-link
- */
- typedef struct {
- QString interfaceName;
- QString interfaceDesc;
- QString interfaceMAC;
- interface_type_t interfaceType;
- wifi_state_t wifiConnected;
- auth_type_t authType;
- int signal;
- QString currentProfileUsed;
- QString wifiSSIDConnected;
- wifi_band_t currentBand;
- } interface_desc_t;
- typedef struct {
- QString wifiSSID;
- QString wifiBSSID;
- int signal;
- wifi_band_t band;
- } wifi_network_t;
- inline QString wifiBandToStr(wifi_band_t band) {
- switch (band) {
- case WIFI_BAND_2_4_GHZ:
- return "2.4 GHz";
- case WIFI_BAND_5_GHZ:
- return "5 GHz";
- default:
- return "Unknown";
- }
- }
- class WiFiManager
- {
- public:
- WiFiManager();
- ~WiFiManager();
- QList<wifi_network_t> scanNetworks(interface_desc_t wifi_interface);
- QList<wifi_network_t> getLastScannedNetworks() { return wifiNetworks; }
- interface_desc_t getLastScannedWifiInterface() { return wifiScannedInterface; }
- QList<interface_desc_t> getWifiInterfaces();
- QList<interface_desc_t> getLastCheckedWifiInterfaces() { return interfacesDescriptions; }
- private:
- QList<interface_desc_t> interfacesDescriptions;
- QList<wifi_network_t> wifiNetworks;
- interface_desc_t wifiScannedInterface;
- QString tempFolderPath;
- };
- #endif // WIFIMANAGER_H
wifimanager.cpp
- #include "wifimanager.h"
- WiFiManager::WiFiManager() {
- }
- WiFiManager::~WiFiManager() {
- interfacesDescriptions.clear();
- }
- QList<interface_desc_t> WiFiManager::getWifiInterfaces() {
- QProcess process;
- qDebug() << "WiFi interfaces getting...";
- // Выполняем команду netsh
- QString cmd = QString("cmd /U /C chcp 437 > nul && netsh wlan show interfaces");
- // process.start("netsh", QStringList() << "wlan" << "show" << "interfaces");
- process.startCommand(cmd);
- process.waitForFinished();
- QString output = QString::fromLocal8Bit(process.readAllStandardOutput());
- QStringList lines = output.split("\n");
- interface_desc_t currentInterface;
- bool parsingInterface = false;
- // Регулярные выражения для разбора
- QRegularExpression nameRe("^Name\\s*:\\s*(.+)$");
- QRegularExpression descRe("^Description\\s*:\\s*(.+)$");
- QRegularExpression macRe("^Physical address\\s*:\\s*([0-9a-fA-F:]+)$");
- QRegularExpression typeRe("^Interface type\\s*:\\s*(.+)$");
- QRegularExpression stateRe("^State\\s*:\\s*(.+)$");
- QRegularExpression ssidRe("^SSID\\s*:\\s*(.+)$");
- QRegularExpression bandRe("^Band\\s*:\\s*(.+)$");
- QRegularExpression authRe("^Authentication\\s*:\\s*(.+)$");
- QRegularExpression signalRe("^Signal\\s*:\\s*(\\d+)%$");
- QRegularExpression profileRe("^Profile\\s*:\\s*(.+)$");
- for (const QString& line : lines) {
- QString trimmedLine = line.trimmed();
- qDebug() << "Line to be parsed: " << line << ", trimmed: " << trimmedLine;
- if (trimmedLine.isEmpty()) {
- if (parsingInterface && currentInterface.interfaceName.length() > 0) {
- qDebug() << "Interface name to be added: " + currentInterface.interfaceName;
- interfacesDescriptions.append(currentInterface);
- parsingInterface = false;
- }
- continue;
- }
- QRegularExpressionMatch match;
- if (!parsingInterface) {
- currentInterface = interface_desc_t();
- currentInterface.currentBand = WIFI_BAND_UNKNOWN;
- currentInterface.signal = 0;
- currentInterface.authType = AUTH_TYPE_UNKNOWN;
- parsingInterface = true;
- qDebug() << "Starting new interface parsing";
- }
- // Парсинг полей
- if ((match = nameRe.match(trimmedLine)).hasMatch()) {
- currentInterface.interfaceName = match.captured(1);
- qDebug() << "Interface name parsed: " << currentInterface.interfaceName;
- // parsingInterface = true;
- // continue;
- }
- else if ((match = descRe.match(trimmedLine)).hasMatch()) {
- currentInterface.interfaceDesc = match.captured(1);
- qDebug() << "Interface desc parsed: " << currentInterface.interfaceDesc;
- // parsingInterface = true;
- // continue;
- }
- else if ((match = macRe.match(trimmedLine)).hasMatch()) {
- currentInterface.interfaceMAC = match.captured(1);
- qDebug() << "Interface MAC parsed: " << currentInterface.interfaceMAC;
- // parsingInterface = true;
- // continue;
- }
- else if ((match = typeRe.match(trimmedLine)).hasMatch()) {
- qDebug() << "interface type parsed: " << match.captured(1);
- currentInterface.interfaceType = match.captured(1) == "Primary" ?
- INTERFACE_TYPE_PRIMARY : INTERFACE_TYPE_SECONDARY;
- // parsingInterface = true;
- // continue;
- }
- else if ((match = stateRe.match(trimmedLine)).hasMatch()) {
- qDebug() << "state parsed: " << match.captured(1);
- currentInterface.wifiConnected = match.captured(1) == "connected" ?
- WIFI_STATE_CONNECTED : WIFI_STATE_DISCONNECTED;
- // parsingInterface = true;
- // continue;
- }
- else if ((match = ssidRe.match(trimmedLine)).hasMatch()) {
- qDebug() << "current SSID parsed: " << match.captured(1);
- currentInterface.wifiSSIDConnected = match.captured(1);
- // parsingInterface = true;
- // continue;
- }
- else if ((match = bandRe.match(trimmedLine)).hasMatch()) {
- QString band = match.captured(1);
- qDebug() << "band parsed: " << band;
- if (band == "2.4 GHz") {
- currentInterface.currentBand = WIFI_BAND_2_4_GHZ;
- } else if (band == "5 GHz") {
- currentInterface.currentBand = WIFI_BAND_5_GHZ;
- } else {
- currentInterface.currentBand = WIFI_BAND_UNKNOWN;
- }
- // parsingInterface = true;
- // continue;
- }
- else if ((match = authRe.match(trimmedLine)).hasMatch()) {
- QString auth = match.captured(1);
- qDebug() << "auth type parsed: " << auth;
- if (auth == "Open") currentInterface.authType = AUTH_TYPE_OPEN;
- else if (auth == "Shared") currentInterface.authType = AUTH_TYPE_SHARED;
- else if (auth == "WPA-Personal") currentInterface.authType = AUTH_TYPE_WPA_PERSONAL;
- else if (auth == "WPA-Enterprise") currentInterface.authType = AUTH_TYPE_WPA_ENTERPRISE;
- else if (auth == "WPA2-Personal") currentInterface.authType = AUTH_TYPE_WPA2_PERSONAL;
- else if (auth == "WPA2-Enterprise") currentInterface.authType = AUTH_TYPE_WPA2_ENTERPRISE;
- else if (auth == "WPA3-Personal") currentInterface.authType = AUTH_TYPE_WPA3_PERSONAL;
- else if (auth == "WPA3-Enterprise") currentInterface.authType = AUTH_TYPE_WPA3_ENTERPRISE;
- else currentInterface.authType = AUTH_TYPE_UNKNOWN;
- // parsingInterface = true;
- // continue;
- }
- else if ((match = signalRe.match(trimmedLine)).hasMatch()) {
- qDebug() << "current signal parsed: " << match.captured(1);
- currentInterface.signal = match.captured(1).toInt();
- // parsingInterface = true;
- // continue;
- }
- else if ((match = profileRe.match(trimmedLine)).hasMatch()) {
- qDebug() << "profile used parsed: " << match.captured(1);
- currentInterface.currentProfileUsed = match.captured(1);
- // parsingInterface = true;
- // continue;
- }
- }
- // Добавляем последний интерфейс, если он есть
- if (parsingInterface && currentInterface.interfaceName.length() > 0) {
- qDebug() << "Last interface name to be added: " + currentInterface.interfaceName;
- interfacesDescriptions.append(currentInterface);
- parsingInterface = false;
- }
- return interfacesDescriptions;
- }
- QList<wifi_network_t> WiFiManager::scanNetworks(interface_desc_t wifi_interface) {
- QProcess process;
- wifiScannedInterface = wifi_interface;
- wifiNetworks.clear();
- // process.start("netsh", {"wlan", "show", "networks", "mode=bssid"});
- QString cmd = QString("cmd /U /C chcp 437 > nul && netsh wlan show networks mode=bssid interface=\"%1\"").arg(wifiScannedInterface.interfaceName);
- process.startCommand(cmd);
- process.waitForFinished();
- QString output = process.readAllStandardOutput();
- QTextStream stream(&output);
- // Регулярные выражения для парсинга
- QRegularExpression ssidRegex("\\bSSID\\b (\\d+)( +):((.+)|\\n)");
- QRegularExpression bssidRegex("( +)\\bBSSID\\b (\\d+)( +): (.+)");
- QRegularExpression signalRegex("( +)\\bSignal\\b( +): (\\d+)(%)");
- QRegularExpression bandRegex("( +)\\bBand\\b( +): (.+)");
- bool parsingNetwork = false;
- wifi_network_t currentNetwork;
- while (!stream.atEnd()) {
- QString line = stream.readLine();
- // Ищем начало новой сети
- QRegularExpressionMatch ssidMatch = ssidRegex.match(line);
- if (ssidMatch.hasMatch()) {
- QString ssid_to_check = ssidMatch.captured(3);
- currentNetwork.wifiSSID = ssid_to_check;
- qDebug() << "Got SSID: " << currentNetwork.wifiSSID;
- parsingNetwork = true;
- continue;
- }
- // Ищем BSSID
- QRegularExpressionMatch bssidMatch = bssidRegex.match(line);
- if (bssidMatch.hasMatch()) {
- currentNetwork.wifiBSSID = bssidMatch.captured(4);
- qDebug() << "Got BSSID: " << currentNetwork.wifiBSSID;
- parsingNetwork = true;
- continue;
- }
- // Ищем уровень сигнала
- QRegularExpressionMatch signalMatch = signalRegex.match(line);
- if (signalMatch.hasMatch()) {
- qDebug() << "Got signal: " << signalMatch.captured(3);
- currentNetwork.signal = signalMatch.captured(3).toInt();
- parsingNetwork = true;
- continue;
- }
- // Ищем полосу частот
- QRegularExpressionMatch bandMatch = bandRegex.match(line);
- if (bandMatch.hasMatch()) {
- QString bandStr = bandMatch.captured(3);
- qDebug() << "Got band: " << bandStr;
- if (bandStr == "2.4 GHz")
- currentNetwork.band = WIFI_BAND_2_4_GHZ;
- else if (bandStr == "5 GHz")
- currentNetwork.band = WIFI_BAND_5_GHZ;
- else
- currentNetwork.band = WIFI_BAND_UNKNOWN;
- // parsingNetwork = true;
- // Добавляем сеть в список
- if (parsingNetwork) {
- currentNetwork.wifiSSID = currentNetwork.wifiSSID.trimmed();
- qDebug() << "WiFi SSID found: " << currentNetwork.wifiSSID << " (" + currentNetwork.wifiBSSID + ")";
- // Excluding empty wifi ssids
- if (!currentNetwork.wifiSSID.isNull())
- if (currentNetwork.wifiSSID.length() > 0)
- wifiNetworks.append(currentNetwork);
- parsingNetwork = false;
- }
- continue;
- }
- }
- return wifiNetworks;
- }
1
94
Вам це подобається? Поділіться в соціальних мережах!
- Останні коментарі
- AK01 квітня 2025 р. 11:41Добрый день. В данный момент работаю над проектом, где необходимо выводить звук из программы в определенное аудиоустройство (колонки, наушники, виртуальный кабель и т.д). Пишу на Qt5.12.12 поско…
- VP09 березня 2025 р. 16:14Здравствуйте! Я устанавливал Qt6 из исходников а также Qt Creator по отдельности. Все компоненты, связанные с разработкой для Android, установлены. Кроме одного... Когда пытаюсь скомпилиров…
- Тепер обговоріть на форумі
- DT14 квітня 2025 р. 15:38Всем привет! На Qt 6.8 MinGW пытаюсь сделать управление подключением WiFi из программы. Пока делаю поддержку Windows, но так же хочу в дальнейшем внедрить и поддержку Linux/MacOS. Для…
- f15 лютого 2025 р. 13:46Подскажите, пожалуйста! Как данный класс можно дополнить, чтобы созданные объекты можно было перемещать мышкой по сцене?
- Не запускается компьютер (точнее работает блок , но сам монитор вообще жесть)В общем я ничего с интернета не скачивала в последнее время. На компе никаких левых пр…
- Вопрос решен. Узнать QModelIndex элемента на который мы перетаскиваем другой элемент, можно с помощью функции indexAt(event->position().toPoint()) представления QTreeViev вызываемой в переопр…