tk1

While loop not working

5 posts in this topic

#1 ·  Posted

Hello,

I am writing a script to monitor when the IP address on my modem changes.  It determines the current IP address, then compares it to the last known address.  If it's different, then it updates the last known with the current, and then waits for it to change.

If the current and last known addresses are the same, then it cycles through a process of alternating between pinging the router's IP address every minute for five minutes, and verifying via external response the current IP vs known.

I have modified weaponx's code for a WMI ping to add a TTL option.  I'll attach my edited version below for your reference.

My goal was to quickly catch when the address changes, but not over-burden the sites that provide the external address.

That's the background.

 

I am having trouble with my ping for five minutes While loop.  For some reason, no matter what I do, I cannot get it to go into the while loop, it just skips right over it completely.  Normally, the condition should be true, so it should process through the loop.  Only when it's not true, should it skip over the loop.

 

Here is my whole code, and the function with the problem is called "fuWaitForIPChange()":

 

#Region ;**** Directives created by AutoIt3Wrapper_GUI ****
#AutoIt3Wrapper_Icon=IP1.ico
#AutoIt3Wrapper_Res_Fileversion=0.0.2.6
#EndRegion ;**** Directives created by AutoIt3Wrapper_GUI ****

#include <Inet.au3>
#include <StaticConstants.au3>
#include <GUIConstantsEx.au3>
#include <GuiButton.au3>
#include <EditConstants.au3>
#include <WindowsConstants.au3>
#include <FileConstants.au3>
#include <Constants.au3>
#include <WMI_Ping.au3>

Global $sExtIPFullPath = "C:\extIP\extIP.txt"
Global $sExtIPHistoryFullPath = "C:\extIP\extIPhist.txt"
Global $sIPChangedTime
Global $sWINIPcurr
Global $sWANIPlast
Global $sPingCheck = "C:\extIP\PingCheck.txt"
Global $sAppVersion = FileGetVersion(@ScriptFullPath)

Opt("GUIOnEventMode", 1) ;Change to OnEvent mode

Global $extIP = GUICreate("Ext IP Mon   " & $sAppVersion, 254, 150, -1, 100, -1, -1)
GUISetOnEvent($GUI_EVENT_CLOSE, "fuClose")
GUICtrlCreateLabel("Last known IP:", 14, 18, 90, 15, $SS_LEFT, -1)
; Include StaticConstants.au3, Left-aligns text in a simple rectangle.
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
GUICtrlSetBkColor(-1, "-2")
Global $sLastKnownIP = GUICtrlCreateLabel("0.0.0.0", 128, 18, 110, 15, $ES_RIGHT)
; Include EditConstants.au3, Right-aligns text in a multiline edit control.
GUICtrlSetFont(-1, 10, 600, 0, "Arial")
GUICtrlCreateLabel("Changed:  ", 14, 46, 90, 23)
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
Global $sLastChanged = GUICtrlCreateLabel($sIPChangedTime, 105, 46, 132, 23, $ES_RIGHT)
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
GUICtrlCreateLabel("Verified:", 14, 75, 90, 15, -1, -1)
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
GUICtrlSetBkColor(-1, "-2")
Global $sTimeChecked = GUICtrlCreateLabel("", 105, 75, 132, 23, $ES_RIGHT)
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
GUICtrlSetBkColor(-1, "-2")
GUICtrlSetTip(-1, "This is the last time the known IP was checked.")
Global $btnRefresh = GUICtrlCreateButton("Refresh", 76, 110, 79, 29, $BS_CENTER, -1)
; Include ButtonConstants.au3, Centers text horizontally in the button rectangle.
GUICtrlSetOnEvent(-1, "fuRefresh")
GUICtrlSetFont(-1, 10, 400, 0, "Arial")
GUICtrlSetTip(-1, "Click to refresh the last known IP and last time it was checked.")
Global $btnExit = GUICtrlCreateButton("Exit", 162, 110, 78, 29, -1, -1)
GUICtrlSetOnEvent(-1, "fuClose")
GUICtrlSetFont(-1, 10, 400, 0, "Arial")

GUISetState(@SW_SHOW, $extIP)

$sWANIPlast = fuReadPubIP() ;Get the last known IP from the file.

While 1
    fuGetWANIP() ;Get current external IP.
    fuUpdateIP() ;Updates the current external IP address.
    fuWaitForIPChange() ;Ping current IP, until unpingable.
WEnd


Func fuReadPubIP() ;Get the last known IP from the file.
    GUISetCursor(1) ;Set the cursor to APPSTARTING
    Local $sIPaddr = FileReadLine($sExtIPFullPath, 1) ;Reads the first line of the file.
    GUICtrlSetData($sLastKnownIP, $sIPaddr) ;Updates IP on the GUI.
    GUICtrlSetData($sTimeChecked, @YEAR & "." & @MON & "." & @MDAY & "   " & @HOUR & ":" & @MIN & ":" & @SEC)
    $sIPChangedTime = FileReadLine($sExtIPFullPath, 3) & "   " & FileReadLine($sExtIPFullPath, 4)
    GUICtrlSetData($sLastChanged, $sIPChangedTime)
    GUISetCursor(2) ;Set the cursor to ARROW
    Return $sIPaddr
EndFunc   ;==>fuReadPubIP

Func fuGetWANIP() ;Get current external IP.
    GUISetCursor(1) ;Set the cursor to APPSTARTING
    $sWINIPcurr = _GetIP() ;Call to the external function in Inet.au3
    GUISetCursor(2) ;Set the cursor to ARROW
EndFunc   ;==>fuGetWANIP

Func fuUpdateIP() ;Updates the current external IP address.
    GUISetCursor(1) ;Set the cursor to APPSTARTING.

    ;Get the IP if it has changed or is missing.
    If $sWANIPlast = "" Or $sWANIPlast <> $sWINIPcurr Then
        FileDelete($sExtIPFullPath)
        FileWriteLine($sExtIPFullPath, $sWINIPcurr) ;Creates the current IP file, & writes the new IP to it.
        Local $sDateChanged = @YEAR & "." & @MON & "." & @MDAY
        Local $sTimeChanged = @HOUR & ":" & @MIN & ":" & @SEC
        ;Add the date and time to the current IP file.
        FileWriteLine($sExtIPFullPath, @CRLF & $sDateChanged & @CRLF & $sTimeChanged)
        ;Update the history file with the date and time.
        FileWriteLine($sExtIPHistoryFullPath, $sDateChanged & @TAB & $sTimeChanged & @TAB & $sWINIPcurr)
        $sWANIPlast = fuReadPubIP()
    EndIf

    GUISetCursor(2) ;Set the cursor to ARROW
EndFunc   ;==>fuUpdateIP

Func fuWaitForIPChange() ;Ping current IP, until unpingable.
    Local $sPingTime
    Local $sResult

    While $sResult = WMI_Ping($sWANIPlast, 1)
        For $i = 1 To 5
            $sPingTime = @HOUR & ":" & @MIN & ":" & @SEC & @TAB & @YEAR & "." & @MON & "." & @MDAY
            FileWriteLine($sPingCheck, $sPingTime)
            Sleep(60000) ;Wait for 1 minute.
            $sWANIPlast = fuReadPubIP()
        Next
        FileDelete($sPingCheck)
    WEnd
EndFunc   ;==>fuWaitForIPChange

Func fuRefresh() ;Refresh the labels in the GUI.
    GUISetCursor(1) ;Set the cursor to APPSTARTING
    GUICtrlSetData($sLastKnownIP, $sWANIPlast)
    GUICtrlSetData($sLastChanged, $sIPChangedTime)
    GUISetCursor(2) ;Set the cursor to ARROW
EndFunc   ;==>fuRefresh

Func fuClose()
    Exit
EndFunc   ;==>fuClose

 

WMI_Ping.au3

Share this post


Link to post
Share on other sites



#2 ·  Posted

Is this what you want?

Func fuWaitForIPChange() ;Ping current IP, until unpingable.
    Local $sPingTime
    Local $sResult

    For $i = 1 To 5
        $sResult = WMI_Ping($sWANIPlast, 1)
        If $result = ?? then ExitLoop
        $sPingTime = @HOUR & ":" & @MIN & ":" & @SEC & @TAB & @YEAR & "." & @MON & "." & @MDAY
        FileWriteLine($sPingCheck, $sPingTime)
        Sleep(60000) ;Wait for 1 minute.
        $sWANIPlast = fuReadPubIP()
    Next
    FileDelete($sPingCheck)
EndFunc   ;==>fuWaitForIPChange

You still need to change the If with the ??  so when it is true it will exit the loop, as I do not have that include with the WMI_Ping UDF so am unsure what it returns. 

Jos


Visit the SciTE4AutoIt3 Download page for the latest versions        Beta files                                                          Forum Rules
 
Live for the present,
Dream of the future,
Learn from the past.
  :)

Share this post


Link to post
Share on other sites

#3 ·  Posted

Without the While loop, that function will only go through the loop 5 times and then end, right?

I want the loop to run continuously until the address changes, which could be in a couple minutes on up to days, weeks, or sometimes months (hopefully).  My ISP is notorious for randomly resetting the modem and since I don't have a static IP, that address changes every time they reset it.

Thank you for that super fast reply!

tk1

Share this post


Link to post
Share on other sites

#4 ·  Posted

@tk1, see these links:

Started with similar problem, solved in a different way https://www.autoitscript.com/forum/topic/135775-while-not-loop-problem/

Nice detailed explanation of how the loop works https://www.autoitscript.com/forum/topic/169143-please-explain-how-while-wend-infinite-loop-works/

In addition, have you looked at the Help File?  I think the example there is exactly what you want.  Simply +1 on each iteration, when limit reached your script will exit. Here https://www.autoitscript.com/autoit3/docs/keywords/While.htm


Skysnake

Why is the snake in the sky?

Share this post


Link to post
Share on other sites

#5 ·  Posted (edited)

Skysnake,

Thank you for the links.  The second one with the explanation was kind of interesting!

 

I was able to resolve this by modifying my While loop a little, taking a little hint from Jos.

Here is the function that replaces the one in the code above, with my modified While in it.  So far, it's working great.

Func fuWaitForIPChange() ;Ping current IP, until unpingable.
    Local $sPingTime
    Local $sResult

    While 1
        $sResult = WMI_Ping($sWANIPlast, 2)
        If Not @error Then
            GUISetCursor(1) ;Set the cursor to APPSTARTING.
            For $i = 1 To 5
                $sPingTime = @HOUR & ":" & @MIN & ":" & @SEC & @TAB & @YEAR & "." & @MON & "." & @MDAY & _
                        @TAB & "Pinged OK"
                FileWriteLine($sPingCheck, $sPingTime)
                Sleep(60000) ;Wait for 1 minute.
                $sWANIPlast = fuReadPubIP()
            Next
            FileDelete($sPingCheck)
        Else
            GUISetCursor(2) ;Set the cursor to ARROW
            ExitLoop
        EndIf
    WEnd
EndFunc   ;==>fuWaitForIPChange

 

A big Thank You to Jos and Skysnake for your help!

tk1

 

Edited by tk1

Share this post


Link to post
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!


Register a new account

Sign in

Already have an account? Sign in here.


Sign In Now