1 (изменено: Malcev, 2023-03-10 16:35:45)

Тема: AHK: Оповещание об отключении/появлении интернета

Тема для обсуждения "Оповещание об отключении/появлении интернета".
http://forum.script-coding.com/viewtopi … 71#p157071

2

Re: AHK: Оповещание об отключении/появлении интернета

А какой именно интернет имеется в виду? Я подключен провайдером к большой локальной сети, у которой может быть выход в глобальный интернет, а может не быть в случае неполадок. Будет ли в последнем варианте считаться, что я подключен к интернету?
Ещё при запуске хорошо бы знать, есть интернет, или нет.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

3

Re: AHK: Оповещание об отключении/появлении интернета

Тут надо проверять.
В msdn об этом мутно написано.
https://learn.microsoft.com/en-us/windo … agerevents
Судя по описанию флагов  должен определять именно наличие интернета.

NLM_CONNECTIVITY_IPV4_INTERNET
Value: 0x40
There is connectivity to the Internet using the IPv4 protocol.

NLM_CONNECTIVITY_IPV6_INTERNET
Value: 0x400
There is connectivity to the Internet using the IPv6 protocol.

https://learn.microsoft.com/en-us/windo … nnectivity

При запуске статус интернета определяется в колбеке:

      if (NetworkListManager.GetConnectivity & 0x40) or (NetworkListManager.GetConnectivity & 0x400)   ; NLM_CONNECTIVITY_IPV4_INTERNET or NLM_CONNECTIVITY_IPV6_INTERNET
         InternetExist := 1
      else
         InternetExist := 0

Можно туда добавить msgbox.

4

Re: AHK: Оповещание об отключении/появлении интернета

Malcev пишет:

Тут надо проверять

Как в следующий раз отключат, проверю.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

5

Re: AHK: Оповещание об отключении/появлении интернета

А ты не собираешься на v2 переходить? Там с новым синтаксисом с ком-интерфейсами более внятно получается, вроде.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

6

Re: AHK: Оповещание об отключении/появлении интернета

Меня пока останавливают 2 момента:
1) Малое количество библиотек для ahk v2.
2) Незаконченные скрипты на ahk v1.
Так что, наверное, если и перейду, то нескоро.

7

Re: AHK: Оповещание об отключении/появлении интернета

Убрал получение статуса интернета при запуске скрипта из колбека.

8

Re: AHK: Оповещание об отключении/появлении интернета

Понадобилось для реального проекта, спасибо, использовал твою наработку.

teadrinker пишет:

Как в следующий раз отключат, проверю.

Сработало, по крайней мере в том конкретном случае.

Malcev пишет:
objrelease(pSink)

Здесь у тебя освобождается память буфера, но не освобождается для каждого RegisterCallback(). Вроде не обязательно создавать буфер через GlobalAlloc(), работает и просто с VarSetCapacity().
Сделал вариант под v2:

#Requires AutoHotkey v2

Persistent
ConnectionWatcher := INetworkListManagerEvents(WatchInternetConnection)
WatchInternetConnection(ConnectionWatcher.IsConnection)

WatchInternetConnection(isConnection) { ; when the internet goes down, a notification appears
    static wnd := '', ExStyles := (WS_EX_NOACTIVATE := 0x8000000) | (WS_EX_TRANSPARENT := 0x00000020)
    if !wnd {
        wnd := Gui('+LastFound -Caption +AlwaysOnTop +Owner +E' . ExStyles)
        WinSetTransparent 210
        wnd.BackColor := 'Red'
        wnd.SetFont('s20', 'Calibri')
        wnd.MarginX := wnd.MarginY := 20
        wnd.AddText(, 'No Internet connection!')
    }
    wnd.%isConnection ? 'Hide' : 'Show'%(isConnection ? unset : 'NA y0')
}

class INetworkListManagerEvents
{
    ipv4 := NLM_CONNECTIVITY_IPV4_INTERNET := 0x0040
    ipv6 := NLM_CONNECTIVITY_IPV6_INTERNET := 0x0400
    CLSID_NetworkListManager      := '{DCB00C01-570F-4A9B-8D69-199FDBA5723B}'
    IID_INetworkListManagerEvents := '{DCB00001-570F-4A9B-8D69-199FDBA5723B}'
    IID_IConnectionPointContainer := '{B196B284-BAB4-101A-B69C-00AA00341D07}'
    IID_IUnknown                  := '{00000000-0000-0000-C000-000000000046}'

    __New(callback) {
        this.callback := callback
        this.CreateVTable()

        this.NetworkListManager := ComObject(this.CLSID_NetworkListManager)
        IConnectionPointContainer := ComObjQuery(this.NetworkListManager, this.IID_IConnectionPointContainer)

        DllCall('Ole32\CLSIDFromString', 'Str', this.IID_INetworkListManagerEvents, 'Ptr', CLSID := Buffer(16))
        ComCall(FindConnectionPoint := 4, IConnectionPointContainer, 'Ptr', CLSID,
                'PtrP', IConnectionPoint := ComValue(VT_UNKNOWN := 0xD, pIConnectionPoint := 0))
        
        ComCall(Advise := 5, IConnectionPoint, 'Ptr', this.vtable.ptr, 'UIntP', &cookie := 0)
        this.IConnectionPoint := IConnectionPoint, this.cookie := cookie
    }

    IsConnection => ( NLM_CONNECTIVITY := this.NetworkListManager.GetConnectivity(),
                      NLM_CONNECTIVITY & this.ipv4) || (NLM_CONNECTIVITY & this.ipv6 )

    CreateVTable() {
        static S_OK := 0
             , Methods := [{name: 'QueryInterface'     , paramCount: 3},
                           {name: 'AddRef'             , paramCount: 1},
                           {name: 'Release'            , paramCount: 1},
                           {name: 'ConnectivityChanged', paramCount: 2}]
        
        this.vtable := Buffer(A_PtrSize * (Methods.Length + 1))
        NumPut('Ptr', this.vtable.Ptr + A_PtrSize, this.vtable)
        for k, v in Methods {
            NumPut('Ptr', CallbackCreate(%v.name%, 'F', v.paramCount), this.vtable, A_PtrSize * k)
        }

        QueryInterface(self, riid, pObj) {
            DllCall('Ole32\StringFromGUID2', 'Ptr', riid, 'Ptr', buf := Buffer(78), 'Int', 39)
            str := StrGet(buf)
            if !(str = this.IID_IUnknown || str = this.IID_INetworkListManagerEvents)
                return E_NOINTERFACE := 0x80004002
            else {
                NumPut('Ptr', self, pObj)
                return S_OK
            }
        }

        AddRef(self)  => 1
        Release(self) => 1

        ConnectivityChanged(self, NLM_CONNECTIVITY) {
            isInternetConnection := (NLM_CONNECTIVITY & this.ipv4) || (NLM_CONNECTIVITY & this.ipv6)
            SetTimer this.callback.Bind(isInternetConnection), -10
            return S_OK
        }
    }

    __Delete() {
        ComCall(Unadvise := 6, this.IConnectionPoint, 'UInt', this.cookie)
        this.IConnectionPoint := ''
        Loop 4 {
            CallbackFree NumGet(this.vtable, A_PtrSize * A_Index, 'Ptr')
        }
    }
}
Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

9

Re: AHK: Оповещание об отключении/появлении интернета

teadrinker пишет:

Здесь у тебя освобождается память буфера, но не освобождается для каждого RegisterCallback().

А разве это необходимо делать?
В справке явно об этом не написано.

Each use of RegisterCallback() allocates a small amount of memory (32 bytes plus system overhead). Since the OS frees this memory automatically when the script exits, any script that allocates a small, fixed number of callbacks does not have to explicitly free the memory. By contrast, a script that calls RegisterCallback() an indefinite/unlimited number of times should explicitly call the following on any unused callbacks:

DllCall("GlobalFree", "Ptr", Address, "Ptr")

10

Re: AHK: Оповещание об отключении/появлении интернета

Ну, так-то можно и после GlobalAlloc не вызывать.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

11 (изменено: Malcev, 2023-05-13 20:11:01)

Re: AHK: Оповещание об отключении/появлении интернета

Если ты про это:

else if (A_EventInfo = 2)
   {
      if (refCount > 0)
      {
         refCount--
         if (refCount = 0)
            DllCall("GlobalFree", "ptr", this, "ptr")
      }
      return refCount
   }

то, думаю, можно смело не вызывать и не посчитывать refcount.
Добавил твою версию для ahk v2 в пост со скриптом.

12

Re: AHK: Оповещание об отключении/появлении интернета

Malcev пишет:

думаю, можно смело не вызывать и не посчитывать refcount.

Ну да. Это если весь код вызывается только один раз при запуске скрипта. Если может вызываться несколько раз, тогда лучше освобождать ресурсы.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

13

Re: AHK: Оповещание об отключении/появлении интернета

Не сильно вникал в код, просто хочу узнать, почему он такой мудрёный? Типа скрипт спрашивает у Windows о наличии интернета? Мне казалось, что всё проще: пингуем несколько стабильных популярных сайтов (или пытаемся скачать с них веб-страницу при помощи UrlDownloadToFile); если все отзываются - значит интернет есть; если все не отзываются - значит интернета нет. Если отзываются, но не все - значит "интернет работает частично".

14

Re: AHK: Оповещание об отключении/появлении интернета

Скрипт не спрашивает у виндовса.
Скрипт подписывается на уведомления от виндовса.

15

Re: AHK: Оповещание об отключении/появлении интернета

ypppu пишет:

пингуем несколько стабильных популярных сайтов (или пытаемся скачать с них веб-страницу при помощи UrlDownloadToFile)

Представь, что скрипт ожидает каких-то сообщений из сети. Как понять, нет сообщений, потому что интернета нет, или потому, что ещё не пришли?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

16

Re: AHK: Оповещание об отключении/появлении интернета

Malcev пишет:

Скрипт подписывается на уведомления от виндовса.

А это надёжный способ узнавать об отключении/появлении интернета?

17

Re: AHK: Оповещание об отключении/появлении интернета

teadrinker пишет:

Представь, что скрипт ожидает каких-то сообщений из сети. Как понять, нет сообщений, потому что интернета нет, или потому, что ещё не пришли?

Если все популярные сайты доступны, но сообщений нет, значит сообщений нет по причине того, что они не пришли. Если же хоть один популярный сайт недоступен, значит с высокой степенью вероятности проблемы у моего местного (или у магистрального) интернет-провайдера (проще говоря, сообщений нет из-за того, что "интернет поломался").

18

Re: AHK: Оповещание об отключении/появлении интернета

ypppu пишет:

А это надёжный способ узнавать об отключении/появлении интернета?

Это официальное апи, поэтому, думаю, да.
https://learn.microsoft.com/en-us/previ … -windows-7

19

Re: AHK: Оповещание об отключении/появлении интернета

Мне встречалось, что Windows 7 (или даже Windows XP) при подключении к сети, в которой IP-адреса раздаёт роутер, вылезало сообщение в трее что-то типа "интернет есть" или "Найдено подключение к интернету". Хотя в WAN-порт роутера вообще не было ничего подключено. Либо туда был воткнуть провод, в котором не было интернета. Поэтому я не доверяю Windows в этом плане.

20

Re: AHK: Оповещание об отключении/появлении интернета

Ну вы можете, если не лень, потестировать скрипт и опубликовать здесь результаты теста.

21

Re: AHK: Оповещание об отключении/появлении интернета

Писать готовый скрипт я не хочу, всего лишь подал идею. Autohotkey, насколько помню, умеет STDIN-STDOUT, следовательно она может запустить в фоне команду ping, получить результат её работы, и по результатам оценить, работает ли интернет или поломался.

22

Re: AHK: Оповещание об отключении/появлении интернета

ypppu пишет:

Если все популярные сайты доступны

То-есть, придётся пинговать "популярные сайты" постоянно?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

23

Re: AHK: Оповещание об отключении/появлении интернета

ypppu пишет:

Писать готовый скрипт я не хочу, всего лишь подал идею

Я имел в виду потестировать скрипт, обсуждаемый в этом топике.

24 (изменено: ypppu, 2023-05-13 23:16:19)

Re: AHK: Оповещание об отключении/появлении интернета

teadrinker, ну да, пинговать, либо UrlDownloadToFile каждые, N секунд.

Malcev, я в принципе не доверяю такого рода уведомлениям от виндовса.

25

Re: AHK: Оповещание об отключении/появлении интернета

ypppu пишет:

ну да, пинговать, либо UrlDownloadToFile каждые, N секунд.

Ну, а не проще ли подписаться на события отключения/подключения интернета, и не выполнять ненужную работу?

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

26 (изменено: ypppu, 2023-05-13 23:26:09)

Re: AHK: Оповещание об отключении/появлении интернета

teadrinker, то же самое скажу: я в принципе не доверяю такого рода уведомлениям от виндовса. Помню, были прецеденты, когда виндусу казалось, что интернет есть, хотя в WAN-порт роутера вообще не было ничего воткнуто. Такое мне встречалось на Wndows XP и  Windows 7, на других ОС не пробовал.

27

Re: AHK: Оповещание об отключении/появлении интернета

ypppu пишет:

Помню, были прецеденты, когда виндусу казалось, что интернет есть, хотя в WAN-порт роутера вообще не было ничего воткнуто.

Ну так ты можешь протестировать этот код для такого случая, и поделиться результатами.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

28

Re: AHK: Оповещание об отключении/появлении интернета

Попробовал на Windows XP и Windows 7. То, что интернет пропал, скрипт понимает секунд за 15-20; то, что интернет опять стал доступен, понимает секунд за 40-50. Или наоборот, уже подзабыл. Для оператора ПК пойдёт. А когда надо быстро продиагностировать, это долговато.

29

Re: AHK: Оповещание об отключении/появлении интернета

ypppu пишет:

Попробовал на Windows XP

Не уверен, что тест был корректным. Дело в том, что эта фича была только на Vista была добавлена.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

30

Re: AHK: Оповещание об отключении/появлении интернета

В WinXP это может называлось "шлюз интернета"? Просто моё предположение. https://rykovodstvo.ru/pars_docs/refs/1 … 9c7bca.jpg

31

Re: AHK: Оповещание об отключении/появлении интернета

А как вы на xp смогли этот скрипт запустить?
По идее там этого апи еще не было.

32

Re: AHK: Оповещание об отключении/появлении интернета

На xp надо так отлавливать:
https://learn.microsoft.com/en-us/previ … 7(v=vs.85)

33

Re: AHK: Оповещание об отключении/появлении интернета

На XP я скрипт не запускал. Просто обрывал интернет и ждал, пока пропадёт иконка "Шлюз интернета" в Сетевых подключениях.
Как в "7", так и в "XP" пинг гораздо быстрее Винды даст знать, что происходит в моменты отвала интернета.

34

Re: AHK: Оповещание об отключении/появлении интернета

Не надо что-либо замерять.
Запустите скрипт на win-7 и отключите интернет.

35

Re: AHK: Оповещание об отключении/появлении интернета

Я тестировал скрипт на 7 и на 10. У меня оба уведомления приходят моментально и там, и там.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

36

Re: AHK: Оповещание об отключении/появлении интернета

Вопрос: приходят моментально после чего?

37

Re: AHK: Оповещание об отключении/появлении интернета

На семёрке я отключал сеть из папки сетевых подключений, на десятке включал airplane mode.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

38

Re: AHK: Оповещание об отключении/появлении интернета

Скрипт потестировал сегодня несколько раз на Windows 7. К роутеру подключал свитч, к свитчу подключал компьютер. Далее запускал скрипт.
Я отключал свитч от роутера и засекал, как быстро скрипт поймёт, что интернет пропал. Потом свитч обратно подключал к роутеру и засекал, как быстро скрипт поймёт, что интернет вернулся.

Короче говоря, скрипт в точности повторял показания Windows. А Windows в половине случаев ошибался. В лучшем случае Windows и скрипт замечали пропадание интернета спустя 2-3 минуты. Бывало и так, что скрипт писал "Internet OK", в то время, когда я уже 10 минут как отключил свитч от роутера.
Ну а в худшем случае Windows и, соответственно, скрипт не замечали пропадание интернета в течение нескольких часов (дольше просто не было времени тестировать).

Ну и перезапуск скрипта, естественно, проблему не решает, поскольку он берёт информацию из Windows.

39

Re: AHK: Оповещание об отключении/появлении интернета

Ну, так это Windows как-то криво работает. У меня, если отключить кабель на семёрке, тоже не сразу реагирует, но через несколько мгновений, в точности, когда в трее показывается иконка с крестиком.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

40

Re: AHK: Оповещание об отключении/появлении интернета

Кстати, возможно, что и пинг будет тупить в это же время.

Разработка AHK-скриптов:
e-mail dfiveg@mail.ru
Telegram jollycoder

41

Re: AHK: Оповещание об отключении/появлении интернета

Иконка с крестиком - это очень простой случай, когда вытыкнули провод компьютера. А в названии темы говорится об оповещении отключения-появления интернета. А отключение-появление интернета может происходить тихо-незаметно, диагностировать его сложнее.

42

Re: AHK: Оповещание об отключении/появлении интернета

Не удивлюсь если семёрка тупит.
ypppu, есть возможность проверить на современной ос?
У меня на win10 при вытаскивании сетевого кабеля - уведомление приходит мгновенно.

43

Re: AHK: Оповещание об отключении/появлении интернета

Потестировать на современной ОС для меня затруднительно. Но, даже если он на 10-ке или 11-ке заработает стабильно - это ограничение по версии ОС. А вот тестилка на базе команды ping была бы актуальна и для стареньких ОС.

44 (изменено: Malcev, 2023-05-16 22:09:49)

Re: AHK: Оповещание об отключении/появлении интернета

Вот по какому алгоритму виндовс работает.
Может у вас NSCI отключен?
https://learn.microsoft.com/en-us/previ … dfrom=MSDN

ypppu пишет:

Но, даже если он на 10-ке или 11-ке заработает стабильно - это ограничение по версии ОС.

Согласен. Я бы с семерок пользователей пересаживал в принудительном порядке.

45

Re: AHK: Оповещание об отключении/появлении интернета

NSCI я не трогал (и вообще только сейчас узнал о его существовании).
По моему мнению, юзеру важно достоверно узнать об отключении/появлении интернета. Пингование удовлетворяет этому требованию и работает надёжно, причём в разных ОС Windows. Ну а Autohotkey позволяет создать такой инструмент.