blademonkey Posted August 3, 2006 Share Posted August 3, 2006 (edited) Hey all, long time no post. I have create a mess of an application. The code is quite sloppy (which is starting to be a bad habit), but that's not the point. here's the background on this file: I wanted to create A gui version of the Unix command tool TAIL. for those of you who are not familiar with tail, it's an app that will list the last lines of a file. the cool part is that you can set it to loop so if the file gets edited from any other process, you will see it in your command window. It's pretty slick. what i did: Created a bastard of a program that does not seem to close once you initiate the Tail button. the trick is that the button calls a function that has a While 1 loop. so in total I have two while loops, but i do not know how to trap exit codes in the second one. I would appreciate if someone could explain to me how I can create an event that applies globally to the entire App. I will post the code along with an attached dummyfile generator I scaped together (in case you dont have a file to tail). Disclaimer: I am fully aware that there are ports of Tail to windows, i have several in addition to some really great hybrids of Grep. Again, this is not the point, I am trying to understant the logic in tail as well as understand the GUI semantics of AUTOIT better. expandcollapse popup; ---------------------------------------------------------------------------- ; ; AutoIt Version: Beta v3.1.1.133 ; Author: Lawrence Scott ; Date: 08/02/2006 ; ; Script Function: ; This program is a GUI version of the Unix Tail utility. ; ; ---------------------------------------------------------------------------- ;----------------------------------------------- ; Script Environment settings | ;----------------------------------------------- #include <File.au3> #include <GUIConstants.au3> #Include <GuiEdit.au3> Opt("GUIOnEventMode", 1) ;---------------------------------------- ; Script Main body | ;---------------------------------------- ; Start GUI Window and Elements creation --> $W_size_l = 700 $Wsize_h =400 $mainWindow = GUICreate("Tails",$W_size_l,$Wsize_h) ;Creates main Window GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") GUISetState(@SW_SHOW) GUICtrlCreateLabel("Please select the file you want to tail", 30, 10) $fileopenButton = GUICtrlCreateButton("Open File",30, 40) GUICtrlSetOnEvent($fileopenButton, "FileopenButton") $TailButton = GUICtrlCreateButton("Tail it",200, 40) GUICtrlSetOnEvent($TailButton, "Tailit") $editControl = GUICtrlCreateEdit("",30,120, $W_size_l-60, ($Wsize_h/3)*2,$WS_VSCROLL+ _ $ES_MULTILINE+$ES_AUTOVSCROLL+$ES_READONLY) $LabelControl = GUICtrlCreateinput("Chosen file",30,80, 300, 20 ) $linecountcontrol = GUICtrlCreateInput("Lines : ",360,80,150,20,$ES_READONLY) $loopQAcontrol = GUICtrlCreateInput("Loop : ",360,40,150,20,$ES_READONLY) ; <-- End GUI Window and Elements creation ; Start Main While loop --> while 1 sleep(1) WEnd ; <-- End Main While loop ;--------------------------------------------------- ; Functions Declarations | ;--------------------------------------------------- ;-------------------- ; Function Tailit() | ;---------------------------------------------------------------------------------------------------- ; Main Function that will actually keep checking the target file for any changes ; via a second While loop func Tailit() ; Function Environment settings --> $error =0 $loopcount = 0 $file = ControlGetText("Tails","",$LabelControl) if not fileexists($file) Then $error = -1 EndIf $openfile = FileOpen($file,0) $count = _FileCountLines($file) $scan= filereadline($file, $count) $file_contents = "" for $x =1 to $count $file_contents = $file_contents & filereadline($file, $x)& @CRLF next GUICtrlSetData($editControl, $file_contents) GUICTrlSetData($linecountcontrol, "Lines : " &$count) _GUICtrlEditLineScroll ($editControl, 0, $count) ; <<- Function Environment settings ; Start While loop --> ; This is where are the processing happens. while 2 $loopcount = $loopcount +1 GUICTrlSetData($loopQAcontrol, "Loop in : " &$loopcount) $recount = _FileCountLines($file) $rescan = filereadline($file, $recount) ; Start Select Block --> Select case $error = -1 MsgBox(0,"Error","no valid file specified, please open a file first") ExitLoop case $rescan <> $scan $file_contents = "" for $x =1 to $count $file_contents = $file_contents & filereadline($file, $x)& @CRLF next GUICtrlSetData($editControl, $file_contents) GUICTrlSetData($linecountcontrol, "Lines : " &$count) _GUICtrlEditLineScroll ($editControl, 0, $recount) $scan = $rescan case $recount <> $count if $recount > $count then $file_contents = "" for $x =1 to $recount $file_contents = $file_contents & filereadline($file, $x)& @CRLF next GUICtrlSetData($editControl, $file_contents) GUICTrlSetData($linecountcontrol, "Lines : " &$recount) _GUICtrlEditLineScroll ($editControl, 0, $recount) $count = $recount elseif $recount < $count Then $file_contents = "" for $x =1 to $recount $file_contents = $file_contents & filereadline($file, $x)& @CRLF next GUICtrlSetData($editControl, $file_contents) GUICTrlSetData($linecountcontrol, "Lines : " &$recount) _GUICtrlEditLineScroll ($editControl, 0, $recount) $linecountcontrol = GUICtrlCreateInput("Lines : " &$recount,360,80,150,40,$ES_READONLY) $count = $recount endif EndSelect ; <-- End Select Block WEnd ; <-- End while Loop fileclose($openfile) EndFunc ;---------------------------------------------------------------------------------------------------- ; End Function Tailit() | ;------------------------- ;---------------------------- ; Function FileopenButton() | ;---------------------------------------------------------------------------------------------------- ; Creates Open File dialog Box, sets the select as the target file to be Tailed func FileopenButton() $selected_file = FileOpenDialog("Open",@ScriptDir,"Text Files (*.*)") GUICtrlSetData($LabelControl, $selected_file) EndFunc ;---------------------------------------------------------------------------------------------------- ; End Function FileopenButton() | ;-------------------------------- Func CLOSEClicked() Exit EndFunc Ya i know, it's REAL ugly, please bare with my code. Oh yea, it's Beta, so dont post the errors from a non-beta compile (those posts tend to spam my threads). Thanks to whoever takes the time to look through it. -Blademonkey Edit: Updated Code and Attachment. dummyfile.au3tail.au3 Edited August 3, 2006 by blademonkey ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
jvanegmond Posted August 3, 2006 Share Posted August 3, 2006 (edited) Lots of text here, but i think what you mean is this: While 1 While $i If $Exit Then ExitLoop 2 Wend Wend Edited August 3, 2006 by Manadar github.com/jvanegmond Link to comment Share on other sites More sharing options...
blademonkey Posted August 3, 2006 Author Share Posted August 3, 2006 (edited) Lots of text here, but i think what you mean is this: While 1 While $i If $Exit Then ExitLoop 2 Wend Wend that didnt really work. I actually just cut and pasted your code into my second while loop and it bombed saying it didnt know what $exit was. I did try adding this: if $GUI_EVENT_CLOSE Then Exitloop endif which sorta worked but it wouldnt go through the whole loop. I think it's related to my script being set on EventMode, not "MessagePolling" Mode. Anyone ? Anyone? Bueler? Bueler? I have updated my code since then (took out the test function). I'll update the post with the new code. Edited August 3, 2006 by blademonkey ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
Don N Posted August 3, 2006 Share Posted August 3, 2006 I was jsut looking over the code, would this be an easy implementation of tail. Uses _FileReadToArray() rather than reading a file line by line and adding to one long string. _Tail: Func _Tail( $i_numTail, $a_readLines ) #calculate which line to end on $endLine = UBound( $a_readLines ) - $i_numTail Dim $a_tailLines[ $i_numTail ] For $iter = UBound( $a_readLines ) - 1 To $endLine Step -1 $a_tailLines[ $iter - $endLine ] = $a_readLines[ $iter ] Next Return $a_tailLines EndFunc oÝ÷ ÙKá1jjey«¢+Ø(¥¹±Õ±Ðí¥±¹ÔÌÐì(¥¹±Õ±ÐíÉÉä¹ÔÌÐì((ÀÌØíÍ}¥±9µôÅÕ½ÐíÑÍйÑáÐÅÕ½Ðì)¥´ÀÌØí}1¥¹Ì)}¥±IQ½ÉÉä ÀÌØíÍ}¥±9µ°ÀÌØí}1¥¹Ì¤((ÀÌØí¥}Ñ¥±1¥¹ÌôÔ((ÀÌØí}Q¥°ô}Q¥° ÀÌØí¥}Ñ¥±1¥¹Ì°ÀÌØí}1¥¹Ì¤()}ÉÉå¥ÍÁ±ä ÀÌØí}Q¥°°ÅÕ½ÐìÅÕ½Ðì¤ Sample Input file( test.txt ): 1 2 3 4 5 6 7 8 9 10 WARNING: No error checking is involved in my example here or in the _Tail function. Add it as needed. _____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper Link to comment Share on other sites More sharing options...
blademonkey Posted August 3, 2006 Author Share Posted August 3, 2006 I was jsut looking over the code, would this be an easy implementation of tail. Uses _FileReadToArray() rather than reading a file line by line and adding to one long string. _Tail: Func _Tail( $i_numTail, $a_readLines ) #calculate which line to end on $endLine = UBound( $a_readLines ) - $i_numTail Dim $a_tailLines[ $i_numTail ] For $iter = UBound( $a_readLines ) - 1 To $endLine Step -1 $a_tailLines[ $iter - $endLine ] = $a_readLines[ $iter ] Next Return $a_tailLines EndFunc oÝ÷ ÙKá1jjey«¢+Ø(¥¹±Õ±Ðí¥±¹ÔÌÐì(¥¹±Õ±ÐíÉÉä¹ÔÌÐì((ÀÌØíÍ}¥±9µôÅÕ½ÐíÑÍйÑáÐÅÕ½Ðì)¥´ÀÌØí}1¥¹Ì)}¥±IQ½ÉÉä ÀÌØíÍ}¥±9µ°ÀÌØí}1¥¹Ì¤((ÀÌØí¥}Ñ¥±1¥¹ÌôÔ((ÀÌØí}Q¥°ô}Q¥° ÀÌØí¥}Ñ¥±1¥¹Ì°ÀÌØí}1¥¹Ì¤()}ÉÉå¥ÍÁ±ä ÀÌØí}Q¥°°ÅÕ½ÐìÅÕ½Ðì¤ Sample Input file( test.txt ): 1 2 3 4 5 6 7 8 9 10 WARNING: No error checking is involved in my example here or in the _Tail function. Add it as needed. Thanks, I just updated my massive code with some comments. I do like the filetoarray function but it tends to slow down when you use on large log files. Also, do you know what the limit on Array elements in Autoit is? I work with logs that have 400+ elements. ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 3, 2006 Moderators Share Posted August 3, 2006 MsgBox(0, '', _Tail(@DesktopDir & '\Test.txt', 5)) Func _Tail($hFile, $i_ReturnLines) Local $sRead = FileRead($hFile), $aFile = StringSplit($sRead, @LF), $sHoldValue For $iCount = (($aFile[0] + 1) - $i_ReturnLines) To $aFile[0] $sHoldValue &= $aFile[$iCount] & @LF Next Return StringTrimRight($sHoldValue, 2) EndFunc Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Don N Posted August 3, 2006 Share Posted August 3, 2006 I think the limit for an array is 16777215, definitely much higher than the 400+ you might need for the log files you must Tail(). _____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper Link to comment Share on other sites More sharing options...
blademonkey Posted August 4, 2006 Author Share Posted August 4, 2006 (edited) Well I rewrote the Tail Function using an array but it still does not solve my problem. how do I break out of the second while loop? thanks -Blademonkey Updated code Edited August 4, 2006 by blademonkey ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 4, 2006 Moderators Share Posted August 4, 2006 Why is it even in a loop? What does $x represent? Your not returning an array, your returning a string (from tail(), (mines faster btw)). Your code isn't even debugable (GUICtrlSetDate($something, ????)). I remember you coding much nicer than this Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
Skruge Posted August 4, 2006 Share Posted August 4, 2006 From a design standpoint, you're using "While 1" and "While 2" (Always true) and having issues trying to break out. Why not use meaningful conditions, for example, "While $LinesRemaining < 10" or "While $Count > 0"? [font="Tahoma"]"Tougher than the toughies and smarter than the smarties"[/font] Link to comment Share on other sites More sharing options...
blademonkey Posted August 4, 2006 Author Share Posted August 4, 2006 From a design standpoint, you're using "While 1" and "While 2" (Always true) and having issues trying to break out. Why not use meaningful conditions, for example, "While $LinesRemaining < 10" or "While $Count > 0"? Partly because I want the app to keep running until specific Controls are pressed ($GUI_EVENT_Close, or the End button). I want the app to continuously monitor the target file and show (realtime) the changes to it. I'm not sure how to trigger an event in the second while loop. I tried while not $GUI_EVENT_CLOSE sleep(100) Wend but it would not process anything in the while loop. So I am stuck, either I can get it to exit, but it does not continuously loop, or I get it to continuously loop and I have to exit through the Autoit Icon in the notification area(FKA Systray) or the process list. ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 4, 2006 Moderators Share Posted August 4, 2006 Right, you aren't going to answer my questions? Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
blademonkey Posted August 4, 2006 Author Share Posted August 4, 2006 (edited) Why is it even in a loop? What does $x represent? Your not returning an array, your returning a string (from tail(), (mines faster btw)). Your code isn't even debugable (GUICtrlSetDate($something, ????)). I remember you coding much nicer than this well it's in a loop because i want it to repeat semi-infinitely. $x is a loop counter to demonstrate whether or not the loop is cycling. I saw that I hashed up the code before i uploaded it so i updated it on the previous post, but here it is: expandcollapse popup#include <File.au3> #include <GUIConstants.au3> #Include <GuiEdit.au3> Opt("GUIOnEventMode", 1) $W_size_l = 700 $Wsize_h =400 $mainWindow = GUICreate("Tails",$W_size_l,$Wsize_h) ;Creates main Window GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") GUISetState(@SW_SHOW) GUICtrlCreateLabel("Please select the file you want to tail", 30, 10) $fileopenButton = GUICtrlCreateButton("Open File",30, 40) GUICtrlSetOnEvent($fileopenButton, "FileopenButton") $TailButton = GUICtrlCreateButton("Tail",200, 40) GUICtrlSetOnEvent($TailButton, "_TailLoop") $editControl = GUICtrlCreateEdit("",30,120, $W_size_l-60, ($Wsize_h/3)*2,$WS_VSCROLL+$ES_MULTILINE+$ES_AUTOVSCROLL+$ES_READONLY) $LabelControl = GUICtrlCreateinput("Chosen file",30,80, 300, 20 ) $linecountcontrol = GUICtrlCreateInput("Lines : ",360,80,150,20,$ES_READONLY) $loopQAcontrol = GUICtrlCreateInput("Loop : ",360,40,150,20,$ES_READONLY) while 1 Sleep(10) WEnd func FileopenButton() $selected_file = FileOpenDialog("Open",@ScriptDir,"Text Files (*.*)") GUICtrlSetData($LabelControl, $selected_file) EndFunc Func _TailLoop() local $x = 0 $TailButton = GUICtrlCreateButton("end",250, 40) GUICtrlSetOnEvent($TailButton, "_Tailend") while 1 $x = $x +1 $results = _Tail("test.txt") GUICtrlSetData($editControl, $results) GUICtrlSetData($loopQAcontrol, $x ) sleep(100) WEnd EndFunc Func _Tail($hFile) dim $aFile local $string = "" _FileReadToArray($hFile,$aFile) for $i = 1 to UBound($aFile) -1 $string = $string & $aFile[$i] & @CRLF next Return $string EndFunc Func _Tailend() MsgBox(0,"Trap", "Tailend clicked!") EndFunc Func CLOSEClicked() Exit EndFunc and the comment about my code not being as good as you remember it: ouch. All I can say is that im focusing on breaking out of the second loop. I have already rewrite my original ugly function into somethin less ugly thanks to you and other people's help. I'm trying to get it to work and optimize the code, so bare with me. PS: didnt see your question till after i replied to Skruge, sorry. Edited August 4, 2006 by blademonkey ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 4, 2006 Moderators Share Posted August 4, 2006 Try this:Func _TailLoop() Local $x = 0 $TailButton = GUICtrlCreateButton("end",250, 40) GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") GUICtrlSetOnEvent($TailButton, "_Tailend") GUISetState() While 1 $x = $x +1 $results = _Tail("test.txt") GUICtrlSetData($editControl, $results) GUICtrlSetData($loopQAcontrol, $x ) Sleep(10) WEnd EndFunc Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
blademonkey Posted August 4, 2006 Author Share Posted August 4, 2006 Try this:Func _TailLoop() Local $x = 0 $TailButton = GUICtrlCreateButton("end",250, 40) GUISetOnEvent($GUI_EVENT_CLOSE, "CLOSEClicked") GUICtrlSetOnEvent($TailButton, "_Tailend") GUISetState() While 1 $x = $x +1 $results = _Tail("test.txt") GUICtrlSetData($editControl, $results) GUICtrlSetData($loopQAcontrol, $x ) Sleep(10) WEnd EndFunc Same results as before. ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
Moderators SmOke_N Posted August 4, 2006 Moderators Share Posted August 4, 2006 Same results as before. Derr me... You are calling another function 10 million times in that loop. I had commented out the function call when I was looking at it. Common sense plays a role in the basics of understanding AutoIt... If you're lacking in that, do us all a favor, and step away from the computer. Link to comment Share on other sites More sharing options...
randallc Posted August 4, 2006 Share Posted August 4, 2006 Derr me... You are calling another function 10 million times in that loop. I had commented out the function call when I was looking at it.Here's a go of what he means;Randall ExcelCOM... AccessCom.. Word2... FileListToArrayNew...SearchMiner... Regexps...SQL...Explorer...Array2D.. _GUIListView...array problem...APITailRW Link to comment Share on other sites More sharing options...
blademonkey Posted August 4, 2006 Author Share Posted August 4, 2006 Derr me... You are calling another function 10 million times in that loop. I had commented out the function call when I was looking at it.yes, that was my point. I am calling it everytime so that it runs and queries the contents of the file. I want it to show the changes made to the file realtime. ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
blademonkey Posted August 4, 2006 Author Share Posted August 4, 2006 Here's a go of what he means;Randallthanks, that's sort of works, but it does not loop. I want it to loop almost infinitely until interrupted by an event. That way it will keep checking the file for new lines, or modifications to the file.As it is, your code only works when you click on tail. What im looking for is for the Tail function to be a continuous loop until interrupted.I thank you both for you efforts, but this is still short of my goal.-Blademonkey ---"Educate the Mind, Make Savage the Body" -Mao Tse Tung Link to comment Share on other sites More sharing options...
Don N Posted August 4, 2006 Share Posted August 4, 2006 Try this, this works for me, continously generating tail until i click the button to stop. expandcollapse popup#include <File.au3> #include <Array.au3> #include <GUIConstants.au3> $s_FileName = "test.txt" Dim $a_Lines Dim $read = True GUICreate( "Tail Function - Continuous File Monitoring", 200, 200 ) $stop = GUICtrlCreateButton( "Click here to end file monitoring.", 10, 10, 180, 180, "0x0700" ) GUISetState( @SW_SHOW ) While $read = True _FileReadToArray( $s_FileName, $a_Lines ) $i_tailLines = 5 $a_Tail = _Tail( $i_tailLines, $a_Lines ) # _ArrayDisplay( $a_Tail, "" ) $msg = GUIGetMsg() If $msg = $GUI_EVENT_CLOSE Or $msg = $stop Then $read = False EndIf WEnd Func _Tail( $i_numTail, $a_readLines ) #calculate which line to end on $endLine = UBound( $a_readLines ) - $i_numTail Dim $a_tailLines[ $i_numTail ] For $iter = UBound( $a_readLines ) - 1 To $endLine Step -1 $a_tailLines[ $iter - $endLine ] = $a_readLines[ $iter ] Next Return $a_tailLines EndFunc Hope this helps. _____________________________________________________"some people live for the rules, I live for exceptions"Wallpaper Changer - Easily Change Your Windows Wallpaper Link to comment Share on other sites More sharing options...
Recommended Posts
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 accountSign in
Already have an account? Sign in here.
Sign In Now