WinHttp.WinHttpRequest IsInternetConnected()

Get help with using AutoHotkey (v1.1 and older) and its commands and hotkeys
User avatar
DataLife
Posts: 460
Joined: 29 Sep 2013, 19:52

WinHttp.WinHttpRequest IsInternetConnected()

Post by DataLife » 05 Apr 2024, 12:17

I found this function by Linear Spoon on the old forum at this address....https://www.autohotkey.com/board/topic/111086-solved-check-if-connected-to-the-internet/

It checks if the computer has access to the internet.

It works really fast (around 200 ms), but I occasionally get errors.
My script checks the status of the internet probably every 5 seconds and stays in the loop until the internet comes back online. It may take hours to get the error.

I have no idea what these errors mean, I have no idea how this function works.

If I can fix the function to not encounter errors that would be great. When I click OK, the script continues, so I would be okay with suppressing the errors. My script can handle if the internet is offline, but visually it is ugly. I am opening the Save as dialog and saving webpages and parsing the mhtml. So, if the mhtml is not what my script is expecting it will try again. So, the continuous closing and opening the webpage and opening and closing the Save As dialog is the ugly part.

I posted the function and screenshots below.

Maybe, I am calling the function to quickly in the loop. After 20 attempts, I display the tooltip and wait 1 second and try again. Maybe I can add a sleep outside of the "if" statement. I will try that but it may be hours before I know if that works.

I am looking for suggestions on how to fix the errors or suppress the errors.

Code: Select all

;Should be compatible with Win XP or higher, 32/64 bit, Unicode or ANSI, latest version.
;code here
;gosub CheckInternet ;(probably about 5 seconds elapses before calling the gosub again)
;more code here
return

CheckInternet:
Loop
 {
  Value := IsInternetConnected()  ;returns 0 or 1 (1 is connected)
  if value = 1
   break
  if a_index > 20
   {
    ToolTip, Waiting on internet to stablize
    sleep 1000
   }
 }
 return
 
IsInternetConnected()
{
  static sz := A_IsUnicode ? 408 : 204, addrToStr := "Ws2_32\WSAAddressToString" (A_IsUnicode ? "W" : "A")
  VarSetCapacity(wsaData, 408)
  if DllCall("Ws2_32\WSAStartup", "UShort", 0x0202, "Ptr", &wsaData)
    return false
  if DllCall("Ws2_32\GetAddrInfoW", "wstr", "dns.msftncsi.com", "wstr", "http", "ptr", 0, "ptr*", results)
  {
    DllCall("Ws2_32\WSACleanup")
    return false
  }
  ai_family := NumGet(results+4, 0, "int")    ;address family (ipv4 or ipv6)
  ai_addr := Numget(results+16, 2*A_PtrSize, "ptr")   ;binary ip address
  ai_addrlen := Numget(results+16, 0, "ptr")   ;length of ip
  DllCall(addrToStr, "ptr", ai_addr, "uint", ai_addrlen, "ptr", 0, "str", wsaData, "uint*", 204)
  DllCall("Ws2_32\FreeAddrInfoW", "ptr", results)
  DllCall("Ws2_32\WSACleanup")
  http := ComObjCreate("WinHttp.WinHttpRequest.5.1")

  if (ai_family = 2 && wsaData = "131.107.255.255:80")
  {
    http.Open("GET", "http://www.msftncsi.com/ncsi.txt")
  }
  else if (ai_family = 23 && wsaData = "[fd3e:4f5a:5b81::1]:80")
  {
    http.Open("GET", "http://ipv6.msftncsi.com/ncsi.txt")
  }
  else
  {
    return false
  }
  http.Send()
  return (http.ResponseText = "Microsoft NCSI") ;ncsi.txt will contain exactly this text
}
image.png
image.png (18.61 KiB) Viewed 265 times
image.png
image.png (17.67 KiB) Viewed 265 times
image.png
image.png (20.54 KiB) Viewed 265 times
Check out my scripts. (MyIpChanger) (ClipBoard Manager) (SavePictureAs)
All my scripts are tested on Windows 10, AutoHotkey 32 bit Ansi unless otherwise stated.

User avatar
lmstearn
Posts: 698
Joined: 11 Aug 2016, 02:32
Contact:

Re: WinHttp.WinHttpRequest IsInternetConnected()

Post by lmstearn » 07 Apr 2024, 01:50

Tried the following:

Code: Select all

;Should be compatible with Win XP or higher, 32/64 bit, Unicode or ANSI, latest version.
#Requires AutoHotkey v1.1.33+
;code here
loop, 50
{
gosub CheckInternet ;(probably about 5 seconds elapses before calling the gosub again)
sleep 5000
}
;more code here
msgbox Completed!
return

CheckInternet:
Loop
 {
  Value := IsInternetConnected()  ;returns 0 or 1 (1 is connected)
  if value = 1
   {
   Tooltip
   break
   }
---The rest snipped---
No errors, there are sure to be some if setting it up for longer.

The first error is common WU error, WININET_E_CONNECTION_ABORTED, usually a hiccup at the other end, or network fault, common with older OS.

WININET_E_TIMEOUT is another old favourite, good news it can be extended as in this thread.

E_PENDING is a generic COM error code:
The data necessary to complete this operation is not yet available.
In most cases these are all transient errors, to silence them, place the COM methods in a try/catch block to trap the errors, and log them to file if you like, see docs.
HTH. :)
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

User avatar
DataLife
Posts: 460
Joined: 29 Sep 2013, 19:52

Re: WinHttp.WinHttpRequest IsInternetConnected()

Post by DataLife » 07 Apr 2024, 20:15

@Imstern
thanks for the suggestions. I modified the function and posted below.

I ran "BITSADMIN /LIST /ALLUSERS /VERBOSE" and 0x80072EFE error code was not in the output. There were two https entries and both were related to a firefox update
That article mentioned "Using a browser, try to download it manually" . The function tries two files. One for ipv4 and the other for ipv6.
On my computer, this statement is TRUE

Code: Select all

if (ai_family = 2 && wsaData = "131.107.255.255:80")
under this IF statement it tries "http://www.msftncsi.com/ncsi.txt". I checked with my browser and that is a good link.

The errors are showing up under the ELSE IF to that statement, when it tries to download "http://ipv6.msftncsi.com/ncsi.txt" (Maybe because I don't use IPV6?)
I put that address in my browser and it says "can't reach this page". So the else statement is running when wsaData is equal to [fd3e:4f5a:5b81::1]:80
Seems to me, if it could not access http://ipv6.msftncsi.com/ncsi.txt then it should return False meaning the internet was not active.
Why would the wsaData be [fd3e:4f5a:5b81::1]:80 every now and then?

I run this function before attempting to open a web page. Over several hours my script may open 100's of pages. But these error messages have shown up only a few times. When they do, it halts my script.

I added "try catch" with a fileappend to the function. Maybe that will ignore the errors. (if not, couldn't I just remove that Else IF statement (else if (ai_family = 23 && wsaData = "[fd3e:4f5a:5b81::1]:80")) and let it "Return False") My script would wait until it returned 1 (True) Seems like that would work.

I also added a timeout

Code: Select all

http.SetTimeouts(0,30000,30000,120000)
modified function

Code: Select all

IsInternetConnected()
{
  static sz := A_IsUnicode ? 408 : 204, addrToStr := "Ws2_32\WSAAddressToString" (A_IsUnicode ? "W" : "A")
  VarSetCapacity(wsaData, 408)
  if DllCall("Ws2_32\WSAStartup", "UShort", 0x0202, "Ptr", &wsaData)
    return false
  if DllCall("Ws2_32\GetAddrInfoW", "wstr", "dns.msftncsi.com", "wstr", "http", "ptr", 0, "ptr*", results)
  {
    DllCall("Ws2_32\WSACleanup")
    return false
  }
  ai_family := NumGet(results+4, 0, "int")    ;address family (ipv4 or ipv6)
  ai_addr := Numget(results+16, 2*A_PtrSize, "ptr")   ;binary ip address
  ai_addrlen := Numget(results+16, 0, "ptr")   ;length of ip
  DllCall(addrToStr, "ptr", ai_addr, "uint", ai_addrlen, "ptr", 0, "str", wsaData, "uint*", 204)
  DllCall("Ws2_32\FreeAddrInfoW", "ptr", results)
  DllCall("Ws2_32\WSACleanup")
  http := ComObjCreate("WinHttp.WinHttpRequest.5.1")
  if (ai_family = 2 && wsaData = "131.107.255.255:80")
  {
	try
      {
	   http.SetTimeouts(0,30000,30000,120000) ;added by me
	   http.Open("GET", "http://www.msftncsi.com/ncsi.txt")
      }
	catch Value
	  {
	   FileAppend,%Value%`n,ErrorLog1.txt
	  }
	
  }
  else if (ai_family = 23 && wsaData = "[fd3e:4f5a:5b81::1]:80")
  {
	try
	  {
	   http.SetTimeouts(0,30000,30000,120000) ;added by Datalife
	   http.Open("GET", "http://ipv6.msftncsi.com/ncsi.txt")
      }
	catch Value
	  {
	   FileAppend,%Value%`n,ErrorLog2.txt
	  }
  }
  else
  {
    return false
  }
  http.Send()
  return (http.ResponseText = "Microsoft NCSI") ;ncsi.txt will contain exactly this text
}
Update:
I found this...viewtopic.php?f=76&t=114135&p=508254&hilit=Linear+Spoon#p508254
If my modifications don't work then I will try how kashmirLZ modified the function.
Check out my scripts. (MyIpChanger) (ClipBoard Manager) (SavePictureAs)
All my scripts are tested on Windows 10, AutoHotkey 32 bit Ansi unless otherwise stated.

User avatar
lmstearn
Posts: 698
Joined: 11 Aug 2016, 02:32
Contact:

Re: WinHttp.WinHttpRequest IsInternetConnected()

Post by lmstearn » 09 Apr 2024, 09:25

Apologies for the late response - how did you go with it?
That link and Malcev's are great, at first glimpse aren't they just another way of doing the same thing? FWIW IPv6 is configured on the router over here and works. Would hazard a guess that whatever url is returning the error to http://ipv6.msftncsi.com has itself an issue with ipv6- most likely an ISP. It's well worth having a go at trapping the source URI's using a packet sniffer, - if at all possible - that said - this is an area where I have practically zero experience.
:arrow: itros "ylbbub eht tuO kaerB" a ni kcuts m'I pleH

Post Reply

Return to “Ask for Help (v1)”