0

I have a process that requires an active VPN connection, but the connection is automatically cut every 8 hours. I need to be able to control that the connection is active and the time left up to the 8 hour limit. In the properties of the windows connections the time appears (attached capture with the data that I need), but I need to know how to read this data.

enter image description here

TylerH
  • 20,799
  • 66
  • 75
  • 101
Delfin Perez
  • 61
  • 10
  • Related: https://stackoverflow.com/questions/24452368/checking-network-connection-using-vba – TylerH Aug 14 '20 at 19:24
  • If you can find/access a COM Wrapper for this Network Connection window, then you should be able to read the values within. – TylerH Aug 14 '20 at 19:29

1 Answers1

3

Try the next approach, please:

Edited, because of the last request:

Please add two new declarations

  1. Copy the next API functions on top of a standard module:
Option Explicit

Private Declare PtrSafe Function FindWindow Lib "User32" Alias "FindWindowA" _
             (ByVal lpClassName As String, ByVal lpWindowName As String) As LongPtr
Private Declare PtrSafe Function FindWindowEx Lib "User32" Alias "FindWindowExA" (ByVal hWnd1 As LongPtr, _
                            ByVal hWnd2 As LongPtr, ByVal lpsz1 As String, ByVal lpsz2 As String) As LongPtr
Private Declare PtrSafe Function SendMessage Lib "User32" Alias "SendMessageA" (ByVal hwnd As LongPtr, _
                                        ByVal wMsg As Long, ByVal wParam As LongPtr, lParam As Any) As Long
Private Declare PtrSafe Function GetWindowTextLength Lib "User32" Alias "GetWindowTextLengthA" (ByVal hwnd As LongPtr) As Long
Private Declare PtrSafe Function GetWindowText Lib "User32" Alias "GetWindowTextA" (ByVal hwnd As LongPtr, _
        ByVal lpString As String, ByVal cch As Long) As Long
Private Declare PtrSafe Function GetWindow Lib "User32" (ByVal hwnd As LongPtr, ByVal wCmd As Long) As Long

And the next Constant:

Private Const GW_HWNDNEXT = 2
'Added after editing:__________________
Private Const WM_LBUTTON_DOWN = &H201
Private Const BM_CLICK = &HF5
'______________________________________
  1. In the same standard module, copy the next Sub. Please, take care to change Duration: from the code, with the Spanish correct variant ('Duración' [with the necessary accent]):
Sub DurationAPI()
   Dim hwndEth As LongPtr, hwndGen As LongPtr, hwndDurlbl As LongPtr, hwndDur As LongPtr
   Dim sStr As String, strWindowTitle As String, durationLbl As String, durT As Date, limitD As Date

   'added after editing:_____________________________
    OpenWiFiConnectionWindow  'open connection window
    AppActivate Application.ActiveWindow.Caption
   '_________________________________________________

   limitD = CDate("08:00:00")
   strWindowTitle = "Estado de Wi-Fi"
   durationLbl = "Duration:" 'Please change here with your exact label title (in Spanish...)
                             'I cannot write duracion: with the necessary accent...
   hwndEth = FindWindow(vbNullString, strWindowTitle): Debug.Print Hex(hwndEth)
    hwndGen = FindWindowEx(hwndEth, 0&, vbNullString, "General"): Debug.Print Hex(hwndGen)
     hwndDurlbl = FindWindowEx(hwndGen, 0&, vbNullString, durationLbl): Debug.Print Hex(hwndDurlbl)
      hwndDur = GetWindow(hwndDurlbl, GW_HWNDNEXT): Debug.Print Hex(hwndDur)
     
      sStr = String(GetWindowTextLength(hwndDur) + 1, Chr$(0))
      GetWindowText hwndDur, sStr, Len(sStr)
      durT = CDate(sStr)
      MsgBox Format(limitD - durT, "hh:mm:ss") & " left until connection will be interrupted!", _
                                          vbInformation, "Time to connection interruption"

      'Added after editing: ____________________________________________________
      Dim hwndClose As LongPtr
      'closing the connection window:
      hwndClose = FindWindowEx(hwndEth, 0&, vbNullString, "&Close"): Debug.Print Hex(hwndClose)
      SendMessage hwndClose, WM_LBUTTON_DOWN, 0&, 0&
      SendMessage hwndClose, BM_CLICK, 0, ByVal 0&
      '_________________________________________________________________________
End Sub
  1. bis Copy the Sub able to show the necessary connection window:
Private Sub OpenWiFiConnectionWindow()
 Dim objApp As Object: Set objApp = CreateObject("Shell.Application")
 Dim objFolder As Object: Set objFolder = objApp.Namespace(&H31&).self.GetFolder
 Dim interface As Variant, interfaceTarget As Object, InterfaceName As String
 
 InterfaceName = "Wi-Fi" 'Please, check here what is show your "Network Connections" folder. It maybe can be slightly different... 
                  'I tested the code on my Ethernet connection, which not was simple "Ethernet". It was "Ethernet 2"...

 For Each interface In objFolder.Items
    If LCase(interface.Name) = LCase(InterfaceName) Then
        Set interfaceTarget = interface:  Exit For
    End If
 Next

 Dim Verb As Variant
 For Each Verb In interfaceTarget.Verbs
    If Verb.Name = "Stat&us" Then
        Verb.DoIt
        Application.Wait Now + TimeValue("0:00:01")
        Exit For
    End If
 Next
End Sub

Please, try this Sub first, in order to be sure that it shows the necessary connection window. If it doesn't, please look in the "Network Connections" folder and change InterfaceName with an appropriate one.

  1. Run the above DurationAPI() Sub.

All the necessary windows handlers are returned in Immediate window. If one of them is 0 (zero), there must be checked to understand what is happening... I used Spy++ to find the windows titles/classes...

For a window with English titles, it returns correctly and almost instant the necessary connection duration time.

FaneDuru
  • 38,298
  • 4
  • 19
  • 27
  • @Delfin Perez: Doesn't my code answer your question? If not, what problem do you face trying it? – FaneDuru Aug 15 '20 at 12:36
  • Thanks for your response. Works fine, but i need get the informacion without open the window with data. i'm looking for the place where the system save that information. – Delfin Perez Aug 15 '20 at 13:54
  • @Delfin Perez: I do not see where you explicitly asked for that... Anyhow, it is very improbable that Windows system keeps track of changes taking place second after second. It will be a useless resources waste. But I think I would be able to programmatically show the connection window, use the above code like it is and finally close it. The single problem, I think, would be the way in which these connection names are shown in "Network Connections" , in your language customisation... – FaneDuru Aug 15 '20 at 14:40
  • @Delfin Perez: Try the updated code, please. Take care of all modifications. I would suggest you to copy everything overwriting the existing version... – FaneDuru Aug 15 '20 at 15:22
  • This solution works fine and i think i can implement in my code. Thanks, – Delfin Perez Aug 18 '20 at 21:34
  • @Delfin Perez: Glad I could help! The main `Sub` can be transformed in a `Function` able to return the existing `MsgBox` content. Or the Time string extracted from the window and you will process it according to your need... – FaneDuru Aug 19 '20 at 07:01