1 (изменено: Malcev, 2023-05-13 20:08:44)

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

https://learn.microsoft.com/en-us/previ … -windows-7
В скрипте отлавливаются события INetworkListManagerEvents.
https://learn.microsoft.com/en-us/windo … agerevents

#Persistent
OnExit, ExitSub
NetworkListManager := ComObjCreate(CLSID_NetworkListManager := "{DCB00C01-570F-4A9B-8D69-199FDBA5723B}")
if (NetworkListManager.GetConnectivity & 0x40) or (NetworkListManager.GetConnectivity & 0x400)   ; NLM_CONNECTIVITY_IPV4_INTERNET or NLM_CONNECTIVITY_IPV6_INTERNET
{
   InternetExist := 1
   msgbox internet ok
}
else
{
   InternetExist := 0
   msgbox no internet
}
Events := [3 ;QueryInterface
          ,1 ;AddRef
          ,1 ;Release
          ,2] ;ConnectivityChanged
VarSetCapacity(CallbackTable, A_PtrSize*Events.MaxIndex(), 0)
For Index, ParameterCount In Events
   NumPut(RegisterCallback("EventHandler", "Fast", ParameterCount, A_Index-1), CallbackTable, A_PtrSize*(A_Index-1))
pSink := DllCall("GlobalAlloc", "uint", 0, "ptr", A_PtrSize+4, "ptr")
NumPut(&CallbackTable, pSink+0, 0)
NumPut(InternetExist, pSink+0, A_PtrSize, "uint")
ConnectionPointContainer := ComObjQuery(NetworkListManager, IID_IConnectionPointContainer := "{B196B284-BAB4-101A-B69C-00AA00341D07}")
VarSetCapacity(CLSID, 16, 0)
DllCall("ole32\CLSIDFromString", "wstr", IID_INetworkListManagerEvents := "{DCB00001-570F-4A9B-8D69-199FDBA5723B}", "ptr", &CLSID)
DllCall(NumGet(NumGet(ConnectionPointContainer + 0) + A_PtrSize*4), "ptr", ConnectionPointContainer, "ptr", &CLSID, "ptr*", ConnectionPoint)   ; IConnectionPointContainer::FindConnectionPoint
ObjRelease(ConnectionPointContainer)
DllCall(NumGet(NumGet(ConnectionPoint + 0) + A_PtrSize*5), "ptr", ConnectionPoint, "ptr", psink, "uint*", nCookie)   ; IConnectionPoint::Advise
return



EventHandler(this, guid = "", ppvObject = "")
{
   static IID_IUnknown, p1, p2, refCount := 1, InternetExist
   if !IID_IUnknown
   {
      VarSetCapacity(p1, 16, 0)
      DllCall("ole32\CLSIDFromString", "wstr", IID_IUnknown := "{00000000-0000-0000-C000-000000000046}", "ptr", &p1)
      VarSetCapacity(p2, 16, 0)
      DllCall("ole32\CLSIDFromString", "wstr", IID_INetworkListManagerEvents := "{DCB00001-570F-4A9B-8D69-199FDBA5723B}", "ptr", &p2)
      InternetExist := NumGet(this+0, A_PtrSize, "uint")
   }
   If (A_EventInfo = 0)
   {
      if DllCall("ole32\IsEqualGUID", "ptr", guid, "ptr", &p1) or DllCall("ole32\IsEqualGUID", "ptr", guid, "ptr", &p2)
      {
         NumPut(this, ppvObject+0)
         refCount++
         return 0
      }
      else
      {
         NumPut(0, ppvObject+0)
         return 0x80004002
      }
   }
   else if (A_EventInfo = 1)
   {
      refCount++
      return refCount
   }
   else if (A_EventInfo = 2)
   {
      if (refCount > 0)
      {
         refCount--
         if (refCount = 0)
            DllCall("GlobalFree", "ptr", this, "ptr")
      }
      return refCount
   }
   else if (A_EventInfo = 3)   ; ConnectivityChanged
   {
      if (guid & 0x40) or (guid & 0x400)   ; NLM_CONNECTIVITY_IPV4_INTERNET or NLM_CONNECTIVITY_IPV6_INTERNET
      {
         if !InternetExist
         {
            InternetExist := 1
            msgbox internet appears
         }
      }
      else
      {
         if InternetExist
         {
            InternetExist := 0
            msgbox internet disappears
         }
      }
      return 0
   }
}

ExitSub:
DllCall(NumGet(NumGet(ConnectionPoint + 0) + A_PtrSize*6), "ptr", ConnectionPoint, "uint", nCookie)   ; IConnectionPoint::Unadvise
ObjRelease(ConnectionPoint)
objrelease(pSink)
ExitApp

Код для ahk v2 от teadrinker:

#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')
        }
    }
}

Тема для обсуждения