Sign in to follow this  
Followers 0
Boltar

There MUST be a way to do this without GOTO

13 posts in this topic

#1 ·  Posted (edited)

Hi Everyone! I hope that all is well with everyone on this fine day!

I am having a terrible time getting some code to work in the new AutoIt v3. I have tried to do this a million ways and just can't make it work, since there is no GOTO command in the language. (I know why we shouldn't use GOTO and I usually don't, honestly, but in this case I can't seem to get anything to work properly). I was hoping I could paste up a scaled down version of my code and ask for suggestions from you talented folks to see if anyone could think of something that would work here short of a GOTO.

This script launches a buggy, crash-prone PC Assets database and reads updates that it should make to it from an input file. It then sends the appropriate keystrokes to the database program to update each record based on what it finds in the input file. It continues until it has processed every line in the input file.

I have this working perfectly. However, the catch about this program is that it randomly (and I do mean RANDOMLY) crashes. All you get is a single window with the title "Error".

So, this is what I did, I wrote 2 functions, one to launch and logon to the database program, and the second to update it. What I am trying to do is write an AdLib function that will trap the "Error" window. When it sees this, I want to kill the database program's process, call the 1st logon function again, and then continue the 2nd function at the next line in the input file.

I have tried SOOOO many different ways to do this, and I just can't figure it out. I can post my real source up if you guys need to see it but it's really, really long and probably confusing if you haven't seen this app. So, I have written a scaled down cleaned up version of the problem I am having that should be easy to read and posted it here. Since GOTO is out of the question, does anyone have any suggestions for this?

Thanks for taking the time to read this I really appreciate it!!

-=-=-=-=CODE BEGINS HERE=-=-=-=-=-=-

;This code launches a buggy database program and reads records updates
;from a file.  It sends keystrokes to the database program to update
;the records.  It will continue this until EOF is reach for the update
;file.  This DB program regularly crashes.  When that happens, I want
;to kill the program's process, relaunch it and relogin, updating it
;at the next entry in the update file.  Everything currently works
;except that after relogging in to the program, the code continues
;execution at the point where the first crash occurred instead of
;at the top of the While loop in UpdateDB(), thus sending the wrong
;keystrokes and totally bombing.


;Main program here
LaunchDB()
UpdateDB()
Exit

;Referenced Functions are here

LaunchDB()
;Code to launch the program and logon
EndFunc

UpdateDB()
AdlibEnable("Crash")
$myfile = FileOpen("test.txt", 0)

While 1
             ;POINT A - WHERE I WANT A CRASH RESTART TO GO
              WinWaitActive("FIRST DB PROMPT","",180)
              $line = FileReadLine($myfile)
              ;CODE NOW PROCESSES $LINE AND HEAVILY
              ;INTERACTS WITH A BUGGY JAVA-BASED DATABASE
              ;
              ;SEVERAL WINWAITACTIVE STATEMENTS
              ;
              ;SENDING KEYS AND MORE KEYS
              ;    
              ;SEVERAL MORE WINWAITACTIVE STATEMENTS
              ;
              ;SENDING KEYS
              ;
              ;SAVE DATABASE UPDATES
              ;
              ;SPIT RESULTS TO A RESULTS FILE
              ;
              ;REPEAT LOOP UNTIL EOF OF $myfile
Wend
EndFunc

Func Crash()
If WinExists("Error") Then
              ;Kill the DB program's process
              ;Report error to log file
              LaunchDB(); Relaunch program and logon again
              ;Now at this point I want the program to return to
              ;POINT A above and simply move on to the next $line
              ;in $myfile.  but NOTHING I have tried works.
EndIf
EndFunc
Edited by Boltar

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

something like :

$Finished = 0
While Not $Finished
    $Crashed = 0
    LaunchDB()
    UpdateDB()
    If $Crashed = 0 then ExitLoop
WEnd    
Exit
;Referenced Functions are here
Func LaunchDB()
;Code to launch the program and logon
EndFunc ;==>LaunchDB 
;
Func UpdateDB()
    WinWaitActive("FIRST DB PROMPT", "", 180)
    $myfile = FileOpen("test.txt", 0)
    AdlibEnable("Crash")
    While Not $Crashed
   ;POINT A - WHERE I WANT A CRASH RESTART TO GO
        $line = FileReadLine($myfile)
   ;
   ;REPEAT LOOP UNTIL EOF OF $myfile
    WEnd
EndFunc ;==>UpdateDB 
;
Func Crash()
    If WinExists("Error") Then
   ;Kill the DB program's process
   ;Report error to log file
        $Crashed = 1
    EndIf
EndFunc ;==>Crash
Edited by JdeB

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

Thank you for the reply! I appreciate the input.

The problem with your solution is that the crash will occur during the UpdateDB()

function. So, when the Crash() AdLib function is called, it will kill the processs,

relaunch the program and log in, but once this function ends it returns control

back to the point in UpdateDB() where it was when the AdLib error trap was called,

thus sending bad keys. There has to be some way for UpdateDB's While/Wend

to knows that there was a crash so that it can stop where it is and ContinueLoop.

Unfortunately, none of my efforts have been successful. I actually tried things like this by having Crash() set a $CrashOccur var to "YES" and put in a test before and after each WinWaitActive prompt for it, but it didn't work AT ALL. Example:

Func UpdateDB()
While
If CrashOccur = "YES" Then
              Global $CrashOccur = "NO"
              ContinueLoop
EndIf       
WinWaitActive("DB PROMPT","",180)
If $CrashOccur = "YES" Then
              Global $CrashOccur = "NO"
              ContinueLoop
EndIf
Wend
EndFunc

Func Crash()
If WinExists("Error") Then
              Global $CrashOccur = "YES"
             ;Kill the DB program's process
             ;Report error to log file
              LaunchDB(); Relaunch program and logon again
             ;Now at this point I want the program to return to
             ;POINT A above and simply move on to the next $line
             ;in $myfile.  but NOTHING I have tried works.
EndIf
EndFunc

But unfortunately this didn't help. The code While loop in UpdateDB would not

reset to the beginning of the loop.

Also, in your example it would actually terminate the script after the first crash. I don't want to end the script after a crash, I want to essentially restart the script after a crash (but not restart the position of the file that we are in so that it will continue updating the list).

Thanks again for taking the time to look at this.

Regards.

Share this post


Link to post
Share on other sites

#4 ·  Posted (edited)

Thank you for the reply!  I appreciate the input.

The problem with your solution is that the crash will occur during the UpdateDB()

function.  So, when the Crash() AdLib function is called, it will kill the processs,

relaunch the program and log in, but once this function ends it returns control

back to the point in UpdateDB() where it was when the AdLib error trap was called,

thus sending bad keys.  There has to be some way for UpdateDB's While/Wend

to knows that there was a crash so that it can stop where it is and ContinueLoop. 

Unfortunately, none of my efforts have been successful. I actually tried things like this by having Crash() set a $CrashOccur var to "YES" and put in a test before and after each WinWaitActive prompt for it, but it didn't work AT ALL.  Example:

<{POST_SNAPBACK}>

When ever a Crash is detected the variable $Crash is set to 1 and will stay on 1 till the main loop, so why not test for that in your update loop ? Edited by JdeB

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

#5 ·  Posted (edited)

Try somthing like this, should do the trick

-=-=-=-=CODE BEGINS HERE=-=-=-=-=-=-

;Main program here
LaunchDB()
UpdateDB()
Exit

;Referenced Functions are here

LaunchDB()
;Code to launch the program and logon
EndFunc

UpdateDB()
AdlibEnable("Crash")
$myfile = FileOpen("test.txt", 0)
Global $startpoint
$startpoint = iniread("inifile.ini" "STARTPOINT", "START",0);will return 0 if not exists

While 1
           ;start at startpoint (can be a line nr from your txt file)
           ;update the var $startpoint every loop
           ;POINT A - WHERE I WANT A CRASH RESTART TO GO
              WinWaitActive("FIRST DB PROMPT","",180)
              $line = FileReadLine($myfile)
            ;CODE NOW PROCESSES $LINE AND HEAVILY
            ;INTERACTS WITH A BUGGY JAVA-BASED DATABASE
            ;
            ;SEVERAL WINWAITACTIVE STATEMENTS
            ;
            ;SENDING KEYS AND MORE KEYS
            ;   
            ;SEVERAL MORE WINWAITACTIVE STATEMENTS
            ;
            ;SENDING KEYS
            ;
            ;SAVE DATABASE UPDATES
            ;
            ;SPIT RESULTS TO A RESULTS FILE
            ;
            ;REPEAT LOOP UNTIL EOF OF $myfile
Wend
EndFunc

Func Crash()
If WinExists("Error") Then
            ;iniwrite("inifile.ini" "STARTPOINT", "START", $startpoint)

            ;Kill the DB program's process
            ;Report error to log file
              Run(your script agian);start your script again at the point of the crash wich will start your db stuff and so
              Exit;exit this instance of the script
EndIf
EndFunc

<{POST_SNAPBACK}>

Edited by TuMbLeWeEd

Share this post


Link to post
Share on other sites

#6 ·  Posted (edited)

When ever a Crash is detected the variable $Crash is set to 1 and will stay on 1 till the main loop, so why not test for that in your update loop ?

<{POST_SNAPBACK}>

Ummm.....

If you read my last post you will see that I did just that, test in the update loop

for the state of $CrashOccur....I put this test before and after every WinWaitActive

statement in the code.

While 1

If $CrashOccur = "YES" Then

Global $CrashOccur = "NO"

ContinueLoop

EndIf

WinWaitActive("DB PROMPT","",180)

If $CrashOccur = "YES" Then

Global $CrashOccur = "NO"

ContinueLoop

EndIf

Wend

I already mentioned that this doesn't work.

Edited by Boltar

Share this post


Link to post
Share on other sites

Ummm.....

If you read my last post you will see that I did just that, test in the update loop

for the state of $CrashOccur....I put this test before and after every WinWaitActive

statement in the code.

While 1

If $CrashOccur = "YES" Then

              Global $CrashOccur = "NO"

              ContinueLoop

EndIf

WinWaitActive("DB PROMPT","",180)

If $CrashOccur = "YES" Then

              Global $CrashOccur = "NO"

              ContinueLoop

EndIf

Wend

I already mentioned that this doesn't work.

<{POST_SNAPBACK}>

I know you mentioned it but don't understand why it wouldn't work..

The code you show doesn't make sense to me but you indicate that you know what you are doing ...... so have fun scripting ... :)


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

I know you mentioned it but don't understand why it wouldn't work..

The code you show doesn't make sense to me but you indicate that you know what you are doing ...... so have fun scripting ...  :)

<{POST_SNAPBACK}>

Ok well thank you for your help then, it was very much appreciated!

Best Wishes.

Share this post


Link to post
Share on other sites

#9 ·  Posted (edited)

What i did is somthing else, at script restart your value will not be there annymore

I just restart the whole script and read from the inifileto where to begin

I wil read a value from a file i have written when it crashed

so imagine your db crashed on line 20 of your txt file

write that nr to an ini file or somting

Close your db app

Start your script again from the current script

Exit current script

Wich will do

Start db app

Read in the inifile where you left off (that was line 20)

Read until you reach line 20 again and and hups you have your starting point again

Used to do it always like that with QA_Run (wich i started with AutoIt)

Or maybe i'm missing somthing here :)

Edited by TuMbLeWeEd

Share this post


Link to post
Share on other sites

TuMbLeWeEd,

That's it!! You're a genius!

I just modified my code a bit to fit your suggestion, I had to end the old script just after launching the second copy of it to avoid a recursion error issue.

I also was prompting the user at the beginning for logon info, so I just instead started pulling that info from an INI file. I had to put in a few lines of code to determine whether this was the first iteration or whether this was a continue from a previous crash, but nothing major. I actually ended up with an INI file and a temp file.

All told, this was a bit complicated (A simple GOTO TOP would have, I think, in this case, been a cleaner solution if it was possible, but hey it works!).

Bottom line: I took your suggestion and it is now working like a charm!!!!

You are the man, score one for Belgium! :)

Thank you very much for taking the time to help me with my dilemma, it now does exactly what I want it to, and I am quite grateful for your input.

This way a human doesn't have to sit there all day and enter data into this database and constantly manually restart it, it's really a beautiful thing.

Best Wishes to all!

P.S. Thank you to JdeB as well for your input.

Share this post


Link to post
Share on other sites

just wondering if setting your original scripts running process priority higher might have eliminated the random crashes.....


[u]Do more with pre-existing apps![/u]ANYGUIv2.8

Share this post


Link to post
Share on other sites

just wondering if setting your original scripts running process priority higher might have eliminated the random crashes.....

<{POST_SNAPBACK}>

Well it wasn't the script that was crashing, it was the database program that it interacts with... It's just a buggy program that we have to use for political reasons.

That thing crashes constantly even when you interact with it manually, it's HIGHLY unstable. Sometimes it crashes while it's just open and running without any interaction at all. Which is why I wanted to write an autoit script to do it for you - it's a pain to use this and constantly restart it while you use it so instead you just setup a spreadsheet with the udpates you want to make and let the autoit script do the work for you, restarting as often as it needs to.

:)

Share this post


Link to post
Share on other sites

While $CrashOccur = "No"
    WinWaitActive("DB PROMPT","",180)
Wend

That'll only run while $CrashOccur is "No", once it changes it breaks out of that while, so you can do whatever you want after that. Maybe something like this:

While 1
    While $CrashOccur = "No"
         WinWaitActive("DB PROMPT","",180)
    Wend
   ;Stuff to do after broken out of loop
WEnd

"I thoroughly disapprove of duels. If a man should challenge me, I would take him kindly and forgivingly by the hand and lead him to a quiet place and kill him." - Mark TwainPatient: "It hurts when I do $var_"Doctor: "Don't do $var_" - Lar.

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
Sign in to follow this  
Followers 0