m88 Posted September 10, 2009 Share Posted September 10, 2009 Hello everyone, I'm kind of a beginner at AutoIt but have used it for a lot of simple things. I've been searching through the forum and trying many different approaches to getting the results that I want from my program but everything I try seems to be overly complicated and I get the feeling that there is an easier way to do this but I'm not sure. My problem is that I need to constantly monitor a text file while I type (or paste into it) for key words and then have some actions occur every time the key words appear. The best I could come up with so far is to use 'ControlGetText' in an infinite loop to always retrieve what is in the file and then I was thinking of using 'StringSplit' to isolate and analyze each word. But the problem with that is it will read the entire file every time, which I'm sure is a big waste of time and space. So what I wanted to ask is if there is a way to only read the last word or couple words that were typed or placed in the document. Every solution I come up with involves reading the entire text every time because I don't know anything else that will read while the document is being edited. Sorry for having such a long explanation but any help would be great. Thanks. Link to comment Share on other sites More sharing options...
Rishav Posted September 10, 2009 Share Posted September 10, 2009 (edited) Lets see if this approach works. Get the line count using _FileCountLines Start an infinite while do loop. Get the line count using _FileCountLines Check if the new file count is greater than previous file count if yes then FileReadLine (the last line count) in the line do StringInStr for the string u are searching for. end infinite loop you can make several variations. put a sleep in the loop to reduce file reading. read the file to array and then do similar operations. etc. Edited September 10, 2009 by Rishav Link to comment Share on other sites More sharing options...
m88 Posted September 10, 2009 Author Share Posted September 10, 2009 Lets see if this approach works. Get the line count using _FileCountLinesStart an infinite while do loop. Get the line count using _FileCountLines Check if the new file count is greater than previous file count if yes then FileReadLine (the last line count) in the line do StringInStr for the string u are searching for.end infinite loopyou can make several variations. put a sleep in the loop to reduce file reading. read the file to array and then do similar operations. etc.That would work if maybe I ran a different program to constantly save the file over and over because FileReadLine reads from the last saved file and not 'live' as something is being typed.. to my understanding. Is there a way to maybe use FileReadLine and FileCountLines as Controls so that the program can count and read from an open file that is constantly being added to? Or should I add a couple lines in the loop that keeps saving this file over and over.. if possible?Thanks. Link to comment Share on other sites More sharing options...
andygo Posted September 10, 2009 Share Posted September 10, 2009 how do you edit your txt file (which editorprogram) while you want it monitored? Link to comment Share on other sites More sharing options...
m88 Posted September 10, 2009 Author Share Posted September 10, 2009 how do you edit your txt file (which editorprogram) while you want it monitored?Sometimes I type into it and sometimes I use a voice recognition software to type for me.. I realize it would probably be a lot easier if it was just typing all the time because I've seen a lot of stuff on here about key-loggers. Link to comment Share on other sites More sharing options...
andygo Posted September 10, 2009 Share Posted September 10, 2009 Sometimes I type into it and sometimes I use a voice recognition software to type for me.. I realize it would probably be a lot easier if it was just typing all the time because I've seen a lot of stuff on here about key-loggers. Link to comment Share on other sites More sharing options...
PsaltyDS Posted September 10, 2009 Share Posted September 10, 2009 Sometimes I type into it and sometimes I use a voice recognition software to type for me.. I realize it would probably be a lot easier if it was just typing all the time because I've seen a lot of stuff on here about key-loggers.Watch your step! Everything you do see about key-loggers here is about how users get banned for discussing them on this forum. That is considered malicious code that will not be discussed here. It doesn't matter how benign your application is. Don't go there. Valuater's AutoIt 1-2-3, Class... Is now in Session!For those who want somebody to write the script for them: RentACoder"Any technology distinguishable from magic is insufficiently advanced." -- Geek's corollary to Clarke's law Link to comment Share on other sites More sharing options...
m88 Posted September 10, 2009 Author Share Posted September 10, 2009 That sounds perfect but is there a command for getting the text from the editor window (other than ControlGetText)? I can't seem to find anything. PS. Thanks for the tip PsaltyDS. Link to comment Share on other sites More sharing options...
m88 Posted September 11, 2009 Author Share Posted September 11, 2009 I've made a program similar to the one Rishav suggested. It gets the number of lines from my file, waits 5 seconds, then sends 'ctrl s' to save and then reads the number of lines again. If the second number is greater, then it takes the last line and does StringInStr to search for the keyword. All of this is in an infinite loop. I was wondering if there is a function similar to _FileCountLines but to count the number of words instead. That way the program will be able to pick up on key words even though a new line was not filled. As a quick fix to this, I made the margins very small so that almost every word is a new line but then I end up missing some lines because I get more than 1 per 5 seconds. I realize I could tweak the timing and put in some code to account for the skipped lines but before I do that I just wanted to know if there is anything that would count the number of words rather than lines. Thanks again. Link to comment Share on other sites More sharing options...
JohnOne Posted September 11, 2009 Share Posted September 11, 2009 I'm, far from a code genius, so I coul not write it, but heres my offering anyway. If you were to stringsplit each line deliminated by " " to and array and return array[0], which I believe is the count of elements in that array at make it , say $var1. Then read to array again returning same, but $var2 If $var2 > $var1, then you return the difference in elements. If you understand my garbled nonesense ? AutoIt Absolute Beginners  Require a serial  Pause Script  Video Tutorials by Morthawt  ipify Monkey's are, like, natures humans. Link to comment Share on other sites More sharing options...
m88 Posted September 11, 2009 Author Share Posted September 11, 2009 (edited) I'm, far from a code genius, so I coul not write it, but heres my offering anyway. If you were to stringsplit each line deliminated by " " to and array and return array[0], which I believe is the count of elements in that array at make it , say $var1. Then read to array again returning same, but $var2 If $var2 > $var1, then you return the difference in elements. If you understand my garbled nonesense ? Haha.. your garbled nonsense is music to my ears. Sounds like it should work.. i'll give it a try and let you know what happened. Thanks. Edited September 11, 2009 by m88 Link to comment Share on other sites More sharing options...
DW1 Posted September 11, 2009 Share Posted September 11, 2009 (edited) Here is a simple example of reading a file only if it is saved (not reading from notepad, but just reading the file). It checks every 60 seconds to see if the file has been modified, and if so, checks the contents for a keyword or phrase: Global $time = 0, $seconds = 60, $keyword = "testword" Global $filename = "C:\test.txt" While 1 If FileExists($filename) Then If Time($filename) <> $time Then $time = Time($filename) If CheckFile($keyword, $filename) = 1 Then Found() EndIf EndIf Sleep($seconds * 1000) WEnd Func Time($file) Return FileGetTime($file, 0, 1) EndFunc Func CheckFile($CheckWord, $CheckFile) $Fhandle = FileOpen( $CheckFile, 0 ) If $Fhandle = -1 Then Return $FileData = FileRead( $Fhandle ) If StringInStr( $FileData, $keyword ) Then Return 1 Else Return 0 EndIf EndFunc Func Found() MsgBox(0, "TEST", 'Found text: "' & $keyword & '" in File: "' & $filename & '"') EndFunc Everything else I can think of would either be too close to a keylogger, or require reading the full control content each time. Edited September 11, 2009 by danwilli AutoIt3 Online Help Link to comment Share on other sites More sharing options...
m88 Posted September 11, 2009 Author Share Posted September 11, 2009 I wrote a quick program that reads in the last line and splits the words up like JohnOne suggested. The way I got around needing to have a whole new line before analyzing the words was to simply send("{enter}") before saving and analyzing the last line. That way when the loop runs again, anything new that was typed will be in the new line and will be sorted. But.. I'm having one last problem. It's probably something stupid that I just don't know how to use properly since I'm not 100% on the syntax of AutoIt yet. At the end of my code once the program picks up the key word 'apple' it displays a message but then I get an error and the program ends rather than looping around again. I think it's probably just the way I'm using the For..Next and I also get the feeling that the way I have my infinite loop set up isn't the best. If some one could take a quick look and let me know it would really help.. small things like this can get really frustrating..lol Do ;Infinite loop Sleep(3000) ;Holds program for 3 seconds Send("^s") ;Saves txt file by sending 'ctrl s' Send("{ENTER}") ;Sends 'enter' to move to next line $LineCount = _FileCountLines("new.txt") ;Gets number of lines in saved file $NewLine = FileReadLine("new.txt", $LineCount) ;Reads last line in saved file $Words = StringSplit($NewLine, " ") ;Splits the words up into an array For $i = 1 to $Words[0] ;Compares words with key, shows msgbox if found If StringCompare($Words[$i], "apple") = 0 then MsgBox(0, "Success", "The apple was found") EndIf Next Until 0 = 1 Sorry if the code comes out bad.. this is my first time posting code. Link to comment Share on other sites More sharing options...
m88 Posted September 11, 2009 Author Share Posted September 11, 2009 Oh sorry didn't see your post danwilli. Thanks a lot for the code, it looks really good.. I just went through it and took some ideas but I would rather not have the program read the entire file every time it scans it since I want it to be searching for key words frequently and the files can get pretty long. Thanks again Link to comment Share on other sites More sharing options...
DW1 Posted September 11, 2009 Share Posted September 11, 2009 (edited) Oh sorry didn't see your post danwilli. Thanks a lot for the code, it looks really good.. I just went through it and took some ideas but I would rather not have the program read the entire file every time it scans it since I want it to be searching for key words frequently and the files can get pretty long.Thanks againreading the entire file at once will be much faster than line by line to determine what you need to "scan".Also, it should only scan the file if the date modified has changed. Edited September 11, 2009 by danwilli AutoIt3 Online Help Link to comment Share on other sites More sharing options...
Rishav Posted September 11, 2009 Share Posted September 11, 2009 Another very simple approach is to see the example provided with #Include <WinAPI.au3> _WinAPI_SetWindowsHookExfucntion. it pretty much does what you ask. Link to comment Share on other sites More sharing options...
dirty Posted March 4, 2010 Share Posted March 4, 2010 I tried to implement this example to my code and had strange results. expandcollapse popup#include <GUIConstantsEx.au3> #include <WindowsConstants.au3> #Include <File.au3> #RequireAdmin $MSGTitle = "hosts Quick Edit" If IsAdmin() Then ;nothing Else MsgBox (64,$MSGTitle," You need administrator rights to use this feature. Error #" & @ScriptLineNumber) Exit EndIf $hostsGUI = GUICreate("hosts Quick Editor",200,462,-1,-1,$WS_BORDER) GUICtrlCreateLabel ('Example:',0,6,42) GUICtrlCreateinput ("127.0.0.1 www.google.com",43,3,157) $Input = GUICtrlCreateEdit ("",0,30,200,370) $ButtonSave = GUICtrlCreateButton ("Save",0,400,100,40) GUICtrlSetFont ($ButtonSave,20,1000,'','',10) $ButtonCancel = GUICtrlCreateButton ("Close",100,400,100,40) GUICtrlSetFont ($ButtonCancel,20,200,'','',10) ;While 1 ;empty loop ; $hosts = (@WindowsDir & "\System32\drivers\etc\hosts") $checkIfSystemhostsExists = FileExists (@WindowsDir & "\System32\drivers\etc\hosts") $checkIfLocalhostsExist = FileExists (@ScriptDir & "\Saved\hosts") If $checkIfSystemhostsExists = 1 And $checkIfLocalhostsExist = 0 Then MsgBox(32,$MSGTitle,"hosts file cant be found in saved folder. Setup will copy system hosts into saved folder. Error #" & @ScriptLineNumber) FileCopy ($hosts,@ScriptDir & "\Saved\hosts", 1+8) ;copy system to local ElseIf $checkIfSystemhostsExists = 1 And $checkIfLocalhostsExist = 1 Then FileCopy (@ScriptDir & "\Saved\hosts", $hosts, 1) ;copy local to system ElseIf $checkIfSystemhostsExists = 0 And $checkIfLocalhostsExist = 1 Then MsgBox(32,$MSGTitle,"hosts file cant be found in system directory. Setup will copy saved hosts to system. Error #" & @ScriptLineNumber) FileCopy (@ScriptDir & "\Saved\hosts", $hosts, 1) ;copy local to system ElseIf $checkIfSystemhostsExists = 0 And $checkIfLocalhostsExist = 0 Then MsgBox(32,$MSGTitle,"hosts file cant be found. Setup will create new one. Error #" & @ScriptLineNumber) FileCopy ($hosts,@ScriptDir & "\Saved\hosts",0+8) ;this will create new local empty file Else MsgBox(16,@ScriptName, "Unknown Error") ;escape EndIf $OpenFile = FileOpen (@ScriptDir & "\Saved\hosts",0) If $OpenFile = -1 Then MsgBox (64,@ScriptName,"Error opening \Saved\hosts. Error #" & @ScriptLineNumber) $fileLocalRead = FileRead ($OpenFile) GUICtrlSetData ($Input, $fileLocalRead) GUISetState(@SW_SHOW, $hostsGUI) While 1 $msg = GUIGetMsg() Switch $msg ;===========================; Case $ButtonSave $Sfile = FileOpen (@ScriptDir & "\Saved\hosts", 2) $readAgain = GUICtrlRead ($Input) FileClose ($OpenFile) FileClose ($Sfile) $SfileAgain = FileOpen (@ScriptDir & "\Saved\hosts", 2) $write = FileWrite ($SfileAgain, $readAgain) FileClose ($SfileAgain) $replacehost = FileCopy (@ScriptDir & "\Saved\hosts", @WindowsDir & "\System32\drivers\etc\hosts", 1) If $write = 0 and $replacehost = 1 Then MsgBox(16,$MSGTitle,"Error writing file. Error #") ElseIf $write = 1 and $replacehost = 0 Then MsgBox(16,$MSGTitle,"Error replacing system file. Error #") ElseIf $write = 0 and $replacehost = 0 Then MsgBox(16,$MSGTitle,"Error writing and replacing system file. Error #") ElseIf $write = 1 and $replacehost = 1 Then $lastLine = FileReadLine (@ScriptDir & "\Saved\hosts",-1) ;Check for same lines Do ;Infinite loop ;$lastLine = FileReadLine (@ScriptDir & "\Saved\hosts",-1) Sleep(100) ;Holds program for 3 seconds Send("^s") ;Saves txt file by sending 'ctrl s' Send("{ENTER}") ;Sends 'enter' to move to next line $LineCount = _FileCountLines(@ScriptDir & "\Saved\hosts") ;Gets number of lines in saved file $NewLine = FileReadLine(@ScriptDir & "\Saved\hosts", $LineCount) ;Reads last line in saved file $Words = StringSplit($NewLine, " ") ;Splits the words up into an array For $i = 1 to $Words[0] ;Compares words with key, shows msgbox if found If StringCompare($Words[$i], $lastLine) = 0 then MsgBox(0, "Success", "The apple was found") EndIf Next Until 0 = 1 ;endcheck for same lines MsgBox(64,$MSGTitle,"Saved") Endif ;===========================; Case $ButtonCancel FileClose ($OpenFile) GUIDelete ($hostsGUI) ExitLoop ;===========================; EndSwitch WEnd It would not only ignore same lines, but also add new once once all lines were scanned. What i hoped to get from this topic is to search editbox or saved files for same lines. If such lines exist then give an error ! Am i at the wrong place for this ? 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