Sign in to follow this  
Followers 0
m88

Monitoring text file for key words live

17 posts in this topic

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.

Share this post


Link to post
Share on other sites



#2 ·  Posted (edited)

Lets see if this approach works. :D

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 by Rishav

Share this post


Link to post
Share on other sites

Lets see if this approach works. :D

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.

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.

Share this post


Link to post
Share on other sites

how do you edit your txt file (which editorprogram) while you want it monitored?

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Posted Image

Share this post


Link to post
Share on other sites

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.

:D


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

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

#11 ·  Posted (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 by m88

Share this post


Link to post
Share on other sites

#12 ·  Posted (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 by danwilli

Share this post


Link to post
Share on other sites

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.

Share this post


Link to post
Share on other sites

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

Share this post


Link to post
Share on other sites

#15 ·  Posted (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 again

reading 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 by danwilli

Share this post


Link to post
Share on other sites

Another very simple approach is to see the example provided with #Include <WinAPI.au3>

_WinAPI_SetWindowsHookExfucntion. it pretty much does what you ask. :D

Share this post


Link to post
Share on other sites

I tried to implement this example to my code and had strange results.

#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 ?

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