Что нового

[Сеть, интернет] Восстановление Wi-Fi соединения

Статус
Закрыто для дальнейших ответов.

Крепыш

Новичок
Сообщения
105
Репутация
2
Есть ноутбук с ОС Windows 8, подключённый по Wi-Fi к роутеру. Иногда Wi-Fi-соединение отваливается. В основном, ноут восстанавливает соединение самостоятельно. Но иногда бывает, что он не может его восстановить. Вручную также не удаётся подключиться к точке доступа. Тогда помогает только отключение/включение сетевого устройства в "Панель управления\Сеть и Интернет\Сетевые подключения".
Возможно ли написать скрипт на AutoIt, который бы диагностировал такие моменты и самостоятельно отключал/включал сетевое устройство при разрыве?
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Код:
$iface = "internet" ; имя подключения

while 1
	Do
		Ping("ya.ru")
	Until @error
	$iMsgBtn = MsgBox(266292, "Тырнет упал!", "Похоже, что интернета у вас нет! Переподключить интерфейс?")
	Select
		Case $iMsgBtn = 6
			ShellExecute('netsh', 'interface set interface "' & $iface & '" disable') ; выключить
			Sleep(1000)
			ShellExecute('netsh', 'interface set interface "' & $iface & '" enable'); включить
			Sleep(5000); ждем интернет 5 сек чтобы все успело прибиндить IP в случаи с DHCP
		Case $iMsgBtn = 7
			Exit
	EndSelect
wend
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
oesoes, спасибо!
А вот можно, чтоб скрипт сам брал из системы имя сетевого подключения?
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Можно-то можно, вот только как он определять будет, вай-фай это или не вай-фай? В системе может быть установленно 10 вай-фай интерфейсов, например. Для этого у них имена и существуют. Попробуй выполнить у себя такую команду:
Код:
netsh wlan show interfaces
, что она выдаст?
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Код:
В системе 1 интерфейс:

    Имя:                                Беспроводная сеть
    Описание:                       Intel(R) Centrino(R) Wireless-N 2230
 

alex33

Скриптер
Сообщения
1,457
Репутация
185
Код:
netsh wlan show interfaces

В системе 1 интерфейс:

    Имя:                                Беспроводное
    Описание:                       Сетевой адаптер Broadcom 802.11n
    Идентификатор GUID:   0e5a7feb-5296-4658-bb28-325465fa50d9
    Физический адрес:       f8:2f:a8:fa:cb:85
    Состояние:                     Подключено
    SSID                   : DIR-320NRU62
    BSSID                  : cc:b2:55:97:c2:1c
    Тип сети:                          Инфраструктура
    Тип радио:                        802.11g
    Проверка подлинности:  WPA2-Personal
    Шифр:                                TKIP
    Режим подключения:      Автоматическое подключение
    Канал:                               9
    Скорость приема (Мбит/с):    54
    Скорость передачи (Мбит/с): 54
    Сигнал:                                     72%
    Профиль                : DIR-320NRU62

    Состояние размещенной сети: Недоступно


Добавлено:
Сообщение автоматически объединено:

Да, кстати можно запустить эту команду из AutoIt, через STD считать и распарсить результат (например регулярным вырожением в массив)...
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Ну можно, только вот у меня это выдает 4 моих беспроводных подключения и выбрать нужное кроме как по имени... хм, ну не знаю ) Отключать и включать все по очереди - не вариант. По моему проще унифицировать имя беспроводного подключения в своих сетях.
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
oesoes,
и они все 4 у тебя одновременно работают?

alex33 сказал(а):
можно запустить эту команду из AutoIt, через STD считать и распарсить результат
Как это сделать?
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
и они все 4 у тебя одновременно работают?
Ну конечно. Зачем бы мне тогда оно надо было. Каждый в свою сеть смотрит.

Овчинка выделки стоит только тогда, когда в системе только один беспроводной интерфейс. Да и вообще, что тебе мешает просто задать ему уникальное имя. И дешево и сердито.
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
В общем получился у меня такой код:
Код:
#include <Misc.au3>
#include <TrayConstants.au3>

Global Const $sTitle = 'Wi-Fi'
_Singleton($sTitle, 0)

Opt('MustDeclareVars', 1)
Opt('TrayOnEventMode', 1)
Opt('TrayMenuMode', 3)
Opt('TrayAutoPause', 0)

Global $sInterface  = 'Беспроводная сеть'  ; имя подключения
Global $bAuto = True

TrayItemSetState(TrayCreateItem('Переподключить'), $TRAY_DEFAULT)
TrayItemSetOnEvent(-1, '_Reconnect')
Global $hAuto = TrayCreateItem('Автоматическое переподключение')
If $bAuto Then TrayItemSetState($hAuto, $TRAY_CHECKED)
TrayItemSetOnEvent($hAuto, '_Chek')
TrayCreateItem('')
TrayItemSetOnEvent(TrayCreateItem('Выход'), '_ExitScript')
TraySetState()

While True
  Sleep(1000)
  If Not Ping('192.168.1.1') Then
    If $bAuto Then
      Sleep(10000)  ; Ждём 10 сек (может подключение само восстановится)
      If Not Ping('192.168.1.1') Then
        _Reconnect()
      EndIf
    EndIf
  EndIf
Wend

Func _Reconnect()
  RunWait('netsh.exe interface set interface "' & $sInterface & '" disable', '', @SW_HIDE)  ; выключить
  Sleep(200)
  RunWait('netsh.exe interface set interface "' & $sInterface & '" enable', '', @SW_HIDE)  ; включить
  Sleep(5000)
EndFunc

Func _Chek()
  If BitAND(TrayItemGetState($hAuto), $TRAY_CHECKED) Then
    $bAuto = True
    TrayItemSetState($hAuto, $TRAY_UNCHECKED)
  Else
    $bAuto = False
    TrayItemSetState($hAuto, $TRAY_CHECKED)
  EndIf
EndFunc

Func _ExitScript()
  Exit
EndFunc


Т.к., разрывается соединение с Wi-Fi роутером, то мониторю именно его. Далее, комп должен постоянно находиться онлайн, поэтому переподключаюсь без лишних вопросов.
Вот бы ещё сделать:
1) При запуске скрипта определять имя беспроводного соединения. Пусть берёт имя первого соединения, если их несколько.
2) Определять состояние подключения в момент запуска скрипта. Если подключено, то устанавливать режим автоматического переподключения при обрыве связи, иначе - работать в ручном режиме.
3) Определять IP роутера с тем чтобы пинговать его.
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Определить IP роутера можно только тогда, когда DHCP включен явно, а иначе нужно перебирать адреса той сети где роутер находится.

1) При запуске скрипта определять имя беспроводного соединения. Пусть берёт имя первого соединения, если их несколько.
2) Определять состояние подключения в момент запуска скрипта. Если подключено, то устанавливать режим автоматического переподключения при обрыве связи, иначе - работать в ручном режиме.
Вот как раз и надо выбирать два поля из ответа команды
Код:
netsh wlan show interfaces
. Поле "Имя" и "Состояние".
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Вот такой шедевр у меня получился:
Код:
#NoTrayIcon
#include <Misc.au3>
#include <TrayConstants.au3>
#include <AutoItConstants.au3>
#include <Encoding.au3>

Global Const $sTitle = 'Wi-Fi'
_Singleton($sTitle, 0)

Opt('MustDeclareVars', 1)
Opt('TrayOnEventMode', 1)
Opt('TrayMenuMode', 3)
Opt('TrayAutoPause', 0)

TrayItemSetState(TrayCreateItem('Переподключить'), $TRAY_DEFAULT)
TrayItemSetOnEvent(-1, '_Reconnect')
Global $hAuto = TrayCreateItem('Автоматическое переподключение')
TrayItemSetOnEvent($hAuto, '_Chek')
TrayCreateItem('')
TrayItemSetOnEvent(TrayCreateItem('Выход'), '_ExitScript')
TraySetState()

Global $sInterface, $sStatus, $sProfile, $sIP, $bAuto = True
Global $iPID, $sOut, $array

While True
  If Not $sInterface Or $sStatus <> 'Подключено' Then
    $sOut = ''
    $iPID = Run('netsh wlan show interfaces', '', @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
    While True
      $sOut &= StdoutRead($iPID)
      If @error Then ExitLoop
    WEnd
    $array = StringRegExp(_Encoding_866To1251($sOut), 'Имя:\s+(.+)(?s).+?Состояние:\s+(?-s)(.+)(?s).+?(?:Профиль\s*)?:\s+(?-s)(.+)', 1)
    If Not $sInterface And UBound($array) >= 1 Then
      $sInterface = $array[0]
    Else
      TraySetToolTip('Беспроводной интерфейс не найден')
    EndIf
    If UBound($array) >= 2 Then $sStatus = $array[1]
    If $sStatus == 'Подключено' Then
      If UBound($array) >= 3 Then $sProfile = $array[2]
      If $bAuto Then TrayItemSetState($hAuto, $TRAY_CHECKED)
      $sIP = '192.168.1.1'  ; Тут надо бы определить IP-адрес роутера
      TraySetToolTip($sInterface & @CRLF & 'Подключено' & @CRLF & $sProfile)
    ElseIf $sInterface Then 
      TraySetToolTip($sInterface & @CRLF & 'Отключено')
    EndIf
  EndIf
  Sleep(1000)
  If $sIP Then
    If Not Ping($sIP) Then
      TraySetToolTip($sInterface & @CRLF & 'Отключено')
      $sStatus = ''
      $sProfile = ''
      If BitAND(TrayItemGetState($hAuto), $TRAY_CHECKED) Then
        Sleep(5000)
        TrayTip($sTitle, 'Wi-Fi соединение отсутствует', 5, 2)
        Sleep(5000)
        If Not Ping($sIP) Then
          TrayTip($sTitle, 'Переподключение', 5)
          _Reconnect()
        EndIf
      EndIf
    Else
      TraySetToolTip($sInterface & @CRLF & 'Подключено' & @CRLF & $sProfile)
    EndIf
  EndIf
Wend

Func _Reconnect()
  RunWait('netsh.exe interface set interface "' & $sInterface & '" disable', '', @SW_HIDE)
  Sleep(200)
  RunWait('netsh.exe interface set interface "' & $sInterface & '" enable', '', @SW_HIDE)
  Sleep(5000)
EndFunc

Func _Chek()
  If BitAND(TrayItemGetState($hAuto), $TRAY_CHECKED) Then
    $bAuto = False
    TrayItemSetState($hAuto, $TRAY_UNCHECKED)
  Else
    $bAuto = True
    TrayItemSetState($hAuto, $TRAY_CHECKED)
  EndIf
EndFunc

Func _ExitScript()
  Exit
EndFunc

Если при запуске скрипта беспроводное соединение отключено, то скрипт находится в режиме ожидания, пока не будет подключения. После подключения к беспроводной сети скрипт раз в секунду пингует IP роутера, и если связь отвалилась, то восстанавливает её.

Осталось определить IP-адрес роутера, к которому подключается ноут. Как это сделать?
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Для проверки наличия тырнета, лучше пинговать не рутер а какой-то ресурс, а то может быть такое, что роутер пингуется, локалка норм, а в интернет не пускает (не оплатили, сбились настройки, прилетело нло). По поводу определения IP рутера: адреса статичные или раздаются роутером по DHCP ?


Добавлено:
Сообщение автоматически объединено:

Хотя, в принципе, если иметь дело с уже настроенным подключением, то можно сделать "ipconfig", которая покажет основные шлюзы забитые на интерфейсах, вот поле основного шлюза - это и есть адрес рутера.
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Утилита написана для того, чтобы восстанавливать Wi-Fi соединение с роутером, которое временами по какой-то причине отваливается и, бывает, само не восстанавливается. Тогда помогает только "передёргивание" интерфейса. Поэтому пинг сторонних ресурсов будет лишним.
IP-адрес раздаётся DHCP роутера. Вот что выдаёт ipconfig:
Код:
Адаптер беспроводной локальной сети Подключение по локальной сети* 2:

   Состояние среды. . . . . . . . : Среда передачи недоступна.
   DNS-суффикс подключения . . . . . :

Адаптер беспроводной локальной сети Беспроводная сеть:

   DNS-суффикс подключения . . . . . :
   Локальный IPv6-адрес канала . . . : fe80:: ...
   IPv4-адрес. . . . . . . . . . . . : 192.168.1.38
   Маска подсети . . . . . . . . . . : 255.255.255.0
   Основной шлюз. . . . . . . . . : 192.168.1.1

Ethernet adapter Ethernet:

   Состояние среды. . . . . . . . : Среда передачи недоступна.
   DNS-суффикс подключения . . . . . :

Туннельный адаптер Подключение по локальной сети* 8:

   Состояние среды. . . . . . . . : Среда передачи недоступна.
   DNS-суффикс подключения . . . . . :

Туннельный адаптер Teredo Tunneling Pseudo-Interface:

   DNS-суффикс подключения . . . . . :
   ...
Я понимаю, что мне нужен IP основного шлюза. Но как взять строку, относящуюся именно к Беспроводной сети, не соображу.


Добавлено:
Сообщение автоматически объединено:

Ну, вот, наверное как-то так будет:
Код:
$sOut = ''
      $iPID = Run('IPConfig', '', @SW_HIDE, $STDERR_CHILD + $STDOUT_CHILD)
      While True
        $sOut &= StdoutRead($iPID)
        If @error Then ExitLoop
      WEnd
      $array = StringRegExp(_Encoding_866To1251($sOut), $sInterface&'(?s).+?Основной шлюз(?-s).+: *(.+)', 1)
      If UBound($array) >= 1 Then $sIP = '192.168.1.1'
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Выполните в cmd:
Код:
ipconfig | findstr "Основной шлюз"
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Код:
Основной шлюз. . . . . . . . . : 192.168.1.1
Основной шлюз. . . . . . . . . : ::
Тут не видно к какому интерфейсу он относится
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Тогда пробуем так в cmd:
Код:
netsh wlan ip show config name="Беспроводная сеть" | find "Основной шлюз"
 

oesoes

xor eax,eax
Сообщения
171
Репутация
9
Блин, ошибся, там должна быть ошибка (с планшета). Вот так пробуемс:
Код:
netsh int ip show config name="Беспроводная сеть" | find "Основной шлюз"
 
Автор
К

Крепыш

Новичок
Сообщения
105
Репутация
2
Код:
Основной шлюз:                      192.168.1.1


Добавлено:
Сообщение автоматически объединено:

Так, а может, также можно с Именем, Состоянием и Профилем сети замутить?
 
Статус
Закрыто для дальнейших ответов.
Верх