Jump to content

Recommended Posts

Posted

Hey all,

I have a very specific function that I need to do for my script that I don't know is possible.

On the systems I made it for, there are clients that all run a program that feeds from data in a folder on a central server.  The script runs on all the clients and if the program comes up with a window in the background that says it can't connect to data,, the script closes the program and related apps, goes into a ping loop for the server until it's successful, and then auto-reconnects.

This is all fine and dandy and works great, but I am trying to think up any possible other scenarios.  For example, restarting.  This is a weird example where the system is still pingable but still unable to connect to data.  The script still works, it just constantly goes into a loop of restarting the program, it coming up with the window saying it can't connect to data, and then it closes everything and tries again.  It will eventually be successful.  But I want it to check the ping AND see if a computer is restarting so it will wait until it's back up before trying.  I am hoping to also implement different error states where it can actually report what's wrong by checking on these things.

Anyway, I realize I'm rambling on a lot.  Basically, I just need to know if there's a way anyone can think of to check if a computer on the network is restarting.  Maybe an If FileExist() function...?  Or something like that?

Posted

How is your script accessing the central server?  File shares, FTP, or another way?  How you connect/reconnect to the server can help determine if it has been rebooted or lost a network connection.  

 

 

Adam

 

  • 2 weeks later...
Posted

Whoa, I never got a notification that someone responded, sorry!

I am connecting to a network share on the server.  Basically, it pings, and if it's successful, it checks to see if it can access a folder on the network share.  If it can, then it tries to boot back up.

It worked fine at first (no idea why), but now upon restart, it loses connection to the data but still apparently thinks it can find the files in the shared folder.  It goes into a Schrodinger type situation, where the data both exists and doesn't exist at the same time...and shoves itself into an infinite loop.

The script does eventually restart the programs successfully, as it is still trying to reconnect.  The issue is that there is a window that pops up saying "CONNECTED" on the customer facing screen.  This will get super confusing for them to see this, and then it constantly goes away and says trying to connect again.  I also have it connected to an error output where if it can't connect to the network, it will output error 1, and if it CAN connect to the network but can't connect to the data, then it will throw error 2.

Anyway, any suggestions per chance??

Posted

Some code that you are using would be helpful.  What code are you using to access the share.  Are you using DriveMapAdd to access the share?  

 

Adam

 

Posted
On 3/19/2019 at 2:11 PM, maloysius said:

but now upon restart, it loses connection to the data but still apparently thinks it can find the files in the shared folder.

Without seeing your code I am guessing but at this point where you do the check for the connection you need to wait at this point until the connection is fully restored before continuing. It should not do anything else until the connection is restored.  

Also you may want to consider waiting a certain amount of time when the program first starts to allow for rebooting process and restoration of system to full working state, all services and programs loaded etc etc...   There should be a call you can make to the system to get if it's current running state, Restart or Shutting down etc...   I can't find a premade function in the manual but if you look at Microsofts websites and internet search there has to be current running state of the system you can get access to.

Posted

Here are two functions I am using .  _DataValidity() assigns the return of _CheckDataValid() into a variable which is checked later.  _CheckDataValid() tries to create a text file in the data folder that needs to be reachable for the POS program to function.  If successful, it returns "B" and deletes the file.  If unsuccessful, it returns "A":

Func _DataValidity()
   Global $Validity = _CheckDataValid()
EndFunc

Func _CheckDataValid()
   Global $DataValid = FileOpen( "\\DDSERVER\DDWIN\BACKUP\Valid.txt", $FO_CREATEPATH)
   If $DataValid = -1 or @error Then
      Return "A"
   EndIf
   If $DataValid <> -1 Then
      FileDelete( "\\DDSERVER\DDWIN\BACKUP\Valid.txt")
      Return "B"
   EndIf
EndFunc

My script checks on these variables to see what to do next in this function:

Func ConnectToData()
   ProcessClose("pos.exe")
   ProcessClose("ddprint.exe")
   ProcessClose("Pos Updater.exe")

   #Region ### START Koda GUI section ### Form=
   Global $Form1 = GUICreate("DataDeputy", 546, 335, -1, -1)
   GUISetIcon("C:\Windows\Oculus.ico", -1)
   Global $Pic1 = GUICtrlCreatePic("C:\DataDeputy\Digital-Dining-Logo.jpg", 64, 16, 172, 100)
   Global $Label1 = GUICtrlCreateLabel("This machine has lost connection to the data.", 32, 152, 482, 33)
   GUICtrlSetFont(-1, 18, 400, 0, "MS Sans Serif")
   Global $Label2 = GUICtrlCreateLabel("Attempting to reconnect...", 144, 200, 274, 33)
   GUICtrlSetFont(-1, 18, 400, 0, "MS Sans Serif")
   Global $Pic2 = GUICtrlCreatePic("C:\DataDeputy\opos logo.jpg", 304, 32, 172, 60)
   Global $Label3 = GUICtrlCreateLabel("If the problem persists, check your network cables, your network equipment, and", 40, 264, 474, 20)
   GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
   Global $Label4 = GUICtrlCreateLabel("your server.  If still unable to connect, please call the help desk at 503-646-1383.", 40, 288, 469, 20)
   GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
   GUISetState(@SW_SHOW)
   #EndRegion ### END Koda GUI section ###

   While 1
      Global $nMsg = GUIGetMsg()
      Global $error = GUICtrlCreateLabel("", 420, 8, 60, 17)

      Sleep(1000)

      _Start()

      _DataValidity()

      If $PingTested <> 0 and $Validity = "A" Then
         ExitLoop
      EndIf

      If $PingTested <> 0 and $Validity = "B" Then
         _Log('(DataDeputy) DATA ERROR: Server is pingable, but unable to reach data.')
         GuiCtrlSetData($error, "ERROR 2")
         _Start()
         _DataValidity()
      Endif

      If $PingTested = "A" Then
         _Log('(DataDeputy) PING ERROR: Server is not reachable on the network.')
         GuiCtrlSetData($error, "ERROR 1")
         _Start()
         _DataValidity()
      Endif

      If $PingTested = "B" Then
         _Log('(DataDeputy) PING ERROR: Server is not reachable on the network.')
         GuiCtrlSetData($error, "ERROR 1")
         _Start()
         _DataValidity()
      Endif

      Switch $nMsg
         Case $GUI_EVENT_CLOSE
            Exit
         Case $Label1
         Case $Label2
      EndSwitch

   WEnd

   _Log('(DataDeputy) Terminal reconnected to data.')

   GUIDelete("DataDeputy")

   ShellExecute( '"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\DDStart.lnk"' )

   SplashTextOn("DataDeputy Message", "CONNECTED!  RESTARTING DIGITAL DINING APPS. PLEASE DO NOT TOUCH SCREEN, MOUSE, OR KEYBOARD...", -1, 200, -1, -1, $DLG_CENTERONTOP, "", 24)

   While 1
      _DataValidity()

      If $Validity = "A" Then
         Sleep(1000)
      EndIf
      If $Validity = "B" Then
         _Log('(DataDeputy) Terminal disconnected from data.')
         SplashOff()
         ConnectToData()
      EndIf
      If WinExists("There was no valid data found.") Then
         WinClose("There was no valid data found.")
         _Log('(DataDeputy) Terminal disconnected from data.')
         SplashOff()
         ConnectToData()
      EndIf
      If ProcessExists( "pos.exe" ) Then
         ExitLoop
      EndIf
      If ProcessExists( "setup232.exe" ) Then
         ExitLoop
      EndIf
   WEnd

   If ProcessExists ( "pos.exe" ) Then
      SplashOff()
      ShellExecute( '"C:\DataDeputy\POS_Updater\POS Updater.exe"' )
      _Log('(DataDeputy) Successfully restarted POS.')
      $StartTimer = TimerInit()
      CheckWindow()
   EndIf

   If ProcessExists ( "setup232.exe" ) Then
      SplashOff()
      SplashTextOn("DataDeputy Message", "PLEASE WAIT WHILE YOUR DIGITAL DINING PROGRAM IS UPGRADED...", -1, 200, -1, -1, $DLG_CENTERONTOP, "", 24)
      DirCreate ( "C:\DDWIN\BACKUP" )
      FileCopy ( "C:\DDWIN\Application\*.ini", "C:\DDWIN\BACKUP", $FC_OVERWRITE )
      _Log('(DataDeputy) Digital Dining is being patched.')

      Do
         Sleep(1000)
      until ProcessExists ( "pos.exe" )
      _Log('(DataDeputy) Digital Dining successfully patched.')

      SplashOff()
      ShellExecute( '"C:\DataDeputy\POS_Updater\POS Updater.exe"' )
      _Log('(DataDeputy) Successfully restarted POS.')
      $StartTimer = TimerInit()
      CheckWindow()
   EndIf

EndFunc

I know that's kind of a lot to parse through, my apologies; I just felt it would be a good idea to just get it all out there so maybe we can see if it's just me making a super simple mistake somewhere.  I am about as far from an AutoIt expert as it's possible to be :)

Just to go over it again, the script works pretty flawlessly unless the computer with the data on it restarts.  Then, the ping works, but the data isn't reachable by the POS program.  This is why I'm trying to implement a way to tell if the data is specifically not reachable, and it seems to think that it IS reachable when the computer restarts (even in post when the computer is booting up).  I don't know, I am super confused here.  I just want my script to be able to tell if the computer is restarting so it doesn't go in a loop of saying it's connected and then disconnecting.

Posted

Just to explain a little more about how it works, it goes into a While loop and runs a ping test and the file create test.  As I have it set up, it shouldn't exit the loop until BOTH of those functions report back successful.  If one or neither come back successful, it will give an error state and then restart the process until successful.

Posted

Thanks @maloysius for posting your code.  it looks like you are accessing the file directly off of the server with FileOpen and FileDelete using the full path.  I've had issues using this method.  It would work sometimes, but other it would not.  I have updated the function to use DriveMapDel and DriveMapAdd, which is what I used to solve my issue.  Using this method, hopefully it will solve your issue as well.  

Func _CheckDataValid()
    Local $sFileShare = "\\DDSERVER\DDWIN"
    Local $sFileShareFile = $sFileShare & "\BACKUP\Valid.txt"
    
    DriveMapDel($sFileShare)
    DriveMapAdd("", $sFileShare)
    If @error Then Return SetError(@error, 0, "A")
    
   Global $DataValid = FileOpen($sFileShareFile, $FO_CREATEPATH)
   If $DataValid = -1 or @error Then
      Return "A"
   EndIf
   If $DataValid <> -1 Then
      FileDelete($sFileShareFile)
      Return "B"
   EndIf
EndFunc

 

Adam

Posted (edited)

My guess was right, you are not checking to see if the file exists before trying to open it.  And since you are using a network drive you should check to make sure the drive exists also.  Check out FileExists and DriveMapGet functions.

Also verify the connection is working before doing anything, use something like InetGetInfo to verify access. 

I am not sure where $PingTested gets initiated because I do not see that in the code you shared but doing checks not just with the connection but also the drive and file itself before trying to open the file is a good idea.  Make sure everything is there and accessible before actually try to do something with it.  

Edited by iAmNewbe
Posted

Instead of returning "A" or "B" return True or False

Func _CheckDataValid()
    Local $bResult = False, $iErr = 0
    Local $sFileShare = "\\DDSERVER\DDWIN"
    Local $sFileShareFile = $sFileShare & "\BACKUP\Valid.txt"
    
    DriveMapDel($sFileShare)
    DriveMapAdd("", $sFileShare)
    $iErr = @error 
    If Not $iErr Then
        Global $DataValid = FileOpen($sFileShareFile, $FO_CREATEPATH)
        If $DataValid <> -1 Then
            FileDelete($sFileShareFile)
            $bResult = True
        Else
            $iErr = 7
        EndIf
    Endif
   SetError($iErr, 0, $bResult)
EndFunc

 

Posted

Really appreciate all the input guys.

I have tried all the ways you've suggested for changing _CheckDataValid(), but now it just always hangs saying ERROR 2 instead of actually restarting.

Maybe I should just post the whole code here:

#include <ButtonConstants.au3>
#include <GUIConstantsEx.au3>
#include <StaticConstants.au3>
#include <WindowsConstants.au3>
#include <MsgBoxConstants.au3>
#include <AutoItConstants.au3>
#include <WinAPIFiles.au3>
#include <File.au3>

#RequireAdmin

Global $StartTimer = TimerInit()
Global $sIP = "DDSERVER"
Global $xi = 0
Global $ii = 999999
Global $DataPath = IniRead("C:\DDWIN\Application\DDDATA.ini", "Data", "Data Path", "Default Value")

CheckWindow()

Func _DataValidity()
   Global $Validity = _CheckDataValid()
EndFunc

Func _CheckDataValid()
    Local $bResult = False, $iErr = 0
    Local $sFileShare = "\\DDSERVER\DDWIN"
    Local $sFileShareFile = $sFileShare & "\BACKUP\Valid.txt"

    DriveMapDel($sFileShare)
    DriveMapAdd("", $sFileShare)
    $iErr = @error
    If Not $iErr Then
        Global $DataValid = FileOpen($sFileShareFile, $FO_CREATEPATH)
        If $DataValid <> -1 Then
            FileDelete($sFileShareFile)
            $bResult = True
        Else
            $iErr = 7
        EndIf
    Endif
   SetError($iErr, 0, $bResult)
EndFunc

Func _Log($sLogEntry)
    Global $Log = FileOpen( "C:\DataDeputy\Log.txt", $FO_APPEND + $FO_CREATEPATH)
    _FileWriteLog($Log, $sLogEntry)
    fileclose($Log)
EndFunc

Func _Start()
   Global $PingTested = _WaitForIP()
EndFunc

Func _WaitForIP()
   While 1
      Global $Ping = Ping("DDSERVER")
      Sleep(1000)
      If $Ping = 0 or @error then
         Return "A"
      Else
         Return $Ping
      Endif
      If $xi = $ii then
         Return "B"
      EndIf
      $xi = $xi +1
   WEnd
EndFunc

Func ConnectToData()
   ProcessClose("pos.exe")
   ProcessClose("ddprint.exe")
   ProcessClose("Pos Updater.exe")

   #Region ### START Koda GUI section ### Form=
   Global $Form1 = GUICreate("DataDeputy", 546, 335, -1, -1)
   GUISetIcon("C:\Windows\Oculus.ico", -1)
   Global $Pic1 = GUICtrlCreatePic("C:\DataDeputy\Digital-Dining-Logo.jpg", 64, 16, 172, 100)
   Global $Label1 = GUICtrlCreateLabel("This machine has lost connection to the data.", 32, 152, 482, 33)
   GUICtrlSetFont(-1, 18, 400, 0, "MS Sans Serif")
   Global $Label2 = GUICtrlCreateLabel("Attempting to reconnect...", 144, 200, 274, 33)
   GUICtrlSetFont(-1, 18, 400, 0, "MS Sans Serif")
   Global $Pic2 = GUICtrlCreatePic("C:\DataDeputy\opos logo.jpg", 304, 32, 172, 60)
   Global $Label3 = GUICtrlCreateLabel("If the problem persists, check your network cables, your network equipment, and", 40, 264, 474, 20)
   GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
   Global $Label4 = GUICtrlCreateLabel("your server.  If still unable to connect, please call the help desk at 503-646-1383.", 40, 288, 469, 20)
   GUICtrlSetFont(-1, 10, 400, 0, "MS Sans Serif")
   GUISetState(@SW_SHOW)
   #EndRegion ### END Koda GUI section ###

   While 1
      Global $nMsg = GUIGetMsg()
      Global $error = GUICtrlCreateLabel("", 420, 8, 60, 17)

      Sleep(1000)

      _Start()

      _DataValidity()

      If $PingTested <> 0 and $Validity = True Then
         ExitLoop
      EndIf

      If $PingTested <> 0 and $Validity = False Then
         _Log('(DataDeputy) DATA ERROR: Server is pingable, but unable to reach data.')
         GuiCtrlSetData($error, "ERROR 2")
         Sleep(1000)
         _Start()
         _DataValidity()
      Endif

      If $PingTested = "A" Then
         _Log('(DataDeputy) PING ERROR: Server is not reachable on the network.')
         GuiCtrlSetData($error, "ERROR 1")
         Sleep(1000)
         _Start()
         _DataValidity()
      Endif

      If $PingTested = "B" Then
         _Log('(DataDeputy) PING ERROR: Server is not reachable on the network.')
         GuiCtrlSetData($error, "ERROR 1")
         Sleep(1000)
         _Start()
         _DataValidity()
      Endif

      Switch $nMsg
         Case $GUI_EVENT_CLOSE
            Exit
         Case $Label1
         Case $Label2
      EndSwitch

   WEnd

   _Log('(DataDeputy) Terminal reconnected to data.')

   GUIDelete("DataDeputy")

   ShellExecute( '"C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Startup\DDStart.lnk"' )

   SplashTextOn("DataDeputy Message", "CONNECTED!  RESTARTING DIGITAL DINING APPS. PLEASE DO NOT TOUCH SCREEN, MOUSE, OR KEYBOARD...", -1, 200, -1, -1, $DLG_CENTERONTOP, "", 24)

   While 1

      If WinExists("There was no valid data found.") Then
         WinClose("There was no valid data found.")
         _Log('(DataDeputy) Terminal disconnected from data.')
         SplashOff()
         ConnectToData()
      EndIf
      If ProcessExists( "pos.exe" ) Then
         ExitLoop
      EndIf
      If ProcessExists( "setup232.exe" ) Then
         ExitLoop
      EndIf
   WEnd

   If ProcessExists ( "pos.exe" ) Then
      SplashOff()
      ShellExecute( '"C:\DataDeputy\POS_Updater\POS Updater.exe"' )
      _Log('(DataDeputy) Successfully restarted POS.')
      $StartTimer = TimerInit()
      CheckWindow()
   EndIf

   If ProcessExists ( "setup232.exe" ) Then
      SplashOff()
      SplashTextOn("DataDeputy Message", "PLEASE WAIT WHILE YOUR DIGITAL DINING PROGRAM IS UPGRADED...", -1, 200, -1, -1, $DLG_CENTERONTOP, "", 24)
      DirCreate ( "C:\DDWIN\BACKUP" )
      FileCopy ( "C:\DDWIN\Application\*.ini", "C:\DDWIN\BACKUP", $FC_OVERWRITE )
      _Log('(DataDeputy) Digital Dining is being patched.')

      Do
         Sleep(1000)
      until ProcessExists ( "pos.exe" )
      _Log('(DataDeputy) Digital Dining successfully patched.')

      SplashOff()
      ShellExecute( '"C:\DataDeputy\POS_Updater\POS Updater.exe"' )
      _Log('(DataDeputy) Successfully restarted POS.')
      $StartTimer = TimerInit()
      CheckWindow()
   EndIf

EndFunc

Func CheckWindow()
   While 1
      If TimerDiff($StartTimer) > 1000 Then
         If WinExists("There was no valid data found.") Then
            WinClose("There was no valid data found.")
            _Log('(DataDeputy) Terminal disconnected from data.')
            ConnectToData()
         EndIf
         Sleep(10)
      EndIf
      If FileExists("\\DDSERVER\DDWIN\BACKUP\DataDeputy\UpdaterUpdate.txt") Then
         ProcessClose ( "POS Updater.exe")

         FileChangeDir("\\DDSERVER\DDWIN\BACKUP\DataDeputy\POS_Updater")
         Global $file1 = FileCopy("POS Updater.exe", "C:\DataDeputy\POS_Updater\", $FC_OVERWRITE)

         FileDelete("\\DDSERVER\DDWIN\BACKUP\DataDeputy\UpdaterUpdate.txt")

         ShellExecute( '"C:\DataDeputy\POS_Updater\POS Updater.exe"' )

         _Log('(DataDeputy) Updated POS Updater.')

         sleep(1000)
      EndIf
   WEnd
EndFunc

I realize that there is some stuff in here that's not being used, just things I've been using for testing...once I've got it all figured out, I will do some cleanup :P

@iAmNewbe, that is exactly what I'm trying to do but failing.  I want it to ping the server, and check to see if the data is accessible.  If it is, then it will exit the loop and try and reconnect.  I took a look at this InetGetInfo function you mentioned, but forgive me, as I can make no sense of the examples or the function itself.  Would this somehow help me accomplish what I'm trying to do??

Posted (edited)
Func _WaitForIP()
   While 1
      Global $Ping = Ping("DDSERVER")
      Sleep(1000)
      If $Ping = 0 or @error then
         Return "A"
      Else
         Return $Ping
      Endif
      If $xi = $ii then
         Return "B"
      EndIf
      $xi = $xi +1
   WEnd
EndFunc

Edit:

If I am reading this function correctly the second If statement never gets reached and the While exits the function returning either "A" or $Ping which could be an error code.

inetGetInfo was just a suggestion to look at to give you ideas. It works with InetGet and gives more information about the download progress of the file.


If you are waiting for the server to reboot you may want to add a timeout.  I rewrote the _WaitForIP function to remove the While loop because it never loops.

 

Func _WaitForIP()
      Global $Ping = Ping("DDSERVER", 15000) ; Try to Connect For 15 Seconds
      If $Ping = 0 OR @error Then
         Return "A"
      Else
         Return $Ping
      Endif 
EndFunc

 

Edited by iAmNewbe
Posted (edited)

If you want the _WaitForIP function to Loop then you want to do this

 

Func _WaitForIP()
    While 1
      If $xi = $ii Then
         Return "B"
      EndIf
      Global $Ping = Ping("DDSERVER", 15000) ; Try to Connect For 15 Seconds
      If $Ping = 0 OR @error Then
          $xi = $xi + 1
         ContinueLoop
      Else
         Return $Ping ; This can return @error code 
      Endif
    WEnd
EndFunc

 

Edited by iAmNewbe

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
  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...