ramoyous Posted October 7, 2014 Posted October 7, 2014 Hello dear friends First i hope you are all fine, my problem is like you see in the topic, i've made a script with AutoIt, in order to monitor a txt file and look fro some words on it, if they exist it will send a mail. the problem is the script can't work and when i start it it run for a few seconds and it stop. Ths script is :.#include <INet.au3>$TextFileName = "C:\Users\X2Z\Desktop\youssef\Adentech\Survey_Monitor_Close_Control_130\Survey Monitor Close Control 1.30\Log.txt"$s_SmtpServer = "smtp.gmail.com"$s_FromName = "Test"$s_FromAddress = "my email"$s_ToAddress = "their email"$s_Subject = "Test test"Dim $as_Body[2]$as_Body[0] = "Alert"$as_Body[1] = "Defaut"; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailFor $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMail($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject, $as_Body, @computername, -1)NextThank you for your help Best regards
jaclaz Posted October 7, 2014 Posted October 7, 2014 I am failing to see the reason to put a whole log file into an array to look for a string in it.You can use FindInFile UDF:http://www.autoitscript.com/forum/topic/132159-findinfile-search-for-a-string-within-files-located-in-a-specific-directory/ jaclaz
ramoyous Posted October 7, 2014 Author Posted October 7, 2014 I am failing to see the reason to put a whole log file into an array to look for a string in it.You can use FindInFile UDF:http://www.autoitscript.com/forum/topic/132159-findinfile-search-for-a-string-within-files-located-in-a-specific-directory/ jaclaz Hello Jaclaz Thanks for your reply, you can specify exactly where i've put the whole log file ? Best regards
jaclaz Posted October 7, 2014 Posted October 7, 2014 Thanks for your reply, you can specify exactly where i've put the whole log file ? I am not sure to understand, the function parses directly the file, i.e. as clearly explained in the given link it is intended as a correspondent to the command line FINDSTR: ; #FUNCTION# ====================================================================================================================; Name ..........: _FindInFile; Description ...: Search for a string within files located in a specific directory.; Syntax ........: _FindInFile($sSearch, $sFilePath[, $sMask = '*'[, $fRecursive = True[, $fLiteral = Default[,; $fCaseSensitive = Default[, $fDetail = Default]]]]]); Parameters ....: $sSearch - The keyword to search for.; $sFilePath - The folder location of where to search.; $sMask - [optional] A list of filetype extensions separated with ';' e.g. '*.au3;*.txt'. Default is all files.; $fRecursive - [optional] Search within subfolders. Default is True.; $fLiteral - [optional] Use the string as a literal search string. Default is False.; $fCaseSensitive - [optional] Use Search is case-sensitive searching. Default is False.; $fDetail - [optional] Show filenames only. Default is False.; Return values .: Success - Returns a one-dimensional and is made up as follows:; $aArray[0] = Number of rows; $aArray[1] = 1st file; $aArray[n] = nth file; Failure - Returns an empty array and sets @error to non-zero; Author ........: guinness; Remarks .......: For more details: http://ss64.com/nt/findstr.html http://ss64.com/nt/findstr.html An example of use is given here:http://www.autoitscript.com/forum/topic/136407-search-for-string-in-txt-files/ jaclaz
ramoyous Posted October 7, 2014 Author Posted October 7, 2014 Thanks for your reply, you can specify exactly where i've put the whole log file ? I am not sure to understand, the function parses directly the file, i.e. as clearly explained in the given link it is intended as a correspondent to the command line FINDSTR: ; #FUNCTION# ====================================================================================================================; Name ..........: _FindInFile; Description ...: Search for a string within files located in a specific directory.; Syntax ........: _FindInFile($sSearch, $sFilePath[, $sMask = '*'[, $fRecursive = True[, $fLiteral = Default[,; $fCaseSensitive = Default[, $fDetail = Default]]]]]); Parameters ....: $sSearch - The keyword to search for.; $sFilePath - The folder location of where to search.; $sMask - [optional] A list of filetype extensions separated with ';' e.g. '*.au3;*.txt'. Default is all files.; $fRecursive - [optional] Search within subfolders. Default is True.; $fLiteral - [optional] Use the string as a literal search string. Default is False.; $fCaseSensitive - [optional] Use Search is case-sensitive searching. Default is False.; $fDetail - [optional] Show filenames only. Default is False.; Return values .: Success - Returns a one-dimensional and is made up as follows:; $aArray[0] = Number of rows; $aArray[1] = 1st file; $aArray[n] = nth file; Failure - Returns an empty array and sets @error to non-zero; Author ........: guinness; Remarks .......: For more details: http://ss64.com/nt/findstr.html http://ss64.com/nt/findstr.html An example of use is given here:http://www.autoitscript.com/forum/topic/136407-search-for-string-in-txt-files/ jaclaz Thank you Jaclaz I'm working in that, also i want to ask if we are using the "InetSmtpMail" how can that work without a server Port ? and a password for the sender account !!! Best regards
ramoyous Posted October 7, 2014 Author Posted October 7, 2014 (edited) Hello, I found this script and it works to send mails, the problems are : when we run script it sends a lot of mail without stop and also it can't monitor the word "alarm" in the text file. this is the script;;##################################; Include;###################################Include<file.au3>;##################################; Variables;##################################$TextFileName = 'C:\Users\X2Z\Desktop\youssef\Adentech\Survey_Monitor_Close_Control_130\Survey Monitor Close Control 1.30\Log.txt'$SmtpServer = "MailServer" ; address for the smtp-server to use - REQUIRED$FromName = "Name" ; name from who the email was sent$FromAddress = "your@Email.Address.com" ; address from where the mail should come$ToAddress = "your@Email.Address.com" ; destination address of the email - REQUIRED$Subject = "Userinfo" ; subject from the email - can be anything you want it to be$Body = "" ; the messagebody from the mail - can be left blank but then you get a blank mail$AttachFiles = "" ; the file(s) you want to attach seperated with a ; (Semicolon) - leave blank if not needed$CcAddress = "CCadress1@test.com" ; address for cc - leave blank if not needed$BccAddress = "BCCadress1@test.com" ; address for bcc - leave blank if not needed$Importance = "Normal" ; Send message priority: "High", "Normal", "Low"$Username = "******" ; username for the account used from where the mail gets sent - REQUIRED$Password = "********" ; password for the account used from where the mail gets sent - REQUIRED$IPPort = 25 ; port used for sending the mail$ssl = 0 ; enables/disables secure socket layer sending - put to 1 if using httpS;~ $IPPort=465 ; GMAIL port used for sending the mail;~ $ssl=1 ; GMAILenables/disables secure socket layer sending - put to 1 if using httpS;##################################; Script;##################################; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error Then MsgBox(0, "Error sending message", "Error code:" & @error & " Description:" & $rc)EndIf;; The UDFFunc _INetSmtpMailCom($s_SmtpServer, $s_FromName, $s_FromAddress, $s_ToAddress, $s_Subject = "", $as_Body = "", $s_AttachFiles = "", $s_CcAddress = "", $s_BccAddress = "", $s_Importance="Normal", $s_Username = "ilyasof90@gmail.com", $s_Password = "talosman2084", $IPPort = 465, $ssl = 1) Local $objEmail = ObjCreate("CDO.Message") $objEmail.From = '"' & $s_FromName & '" <' & $s_FromAddress & '>' $objEmail.To = $s_ToAddress Local $i_Error = 0 Local $i_Error_desciption = "" If $s_CcAddress <> "" Then $objEmail.Cc = $s_CcAddress If $s_BccAddress <> "" Then $objEmail.Bcc = $s_BccAddress $objEmail.Subject = $s_Subject If StringInStr($as_Body, "<") And StringInStr($as_Body, ">") Then $objEmail.HTMLBody = $as_Body Else $objEmail.Textbody = $as_Body & @CRLF EndIf If $s_AttachFiles <> "" Then Local $S_Files2Attach = StringSplit($s_AttachFiles, ";") For $x = 1 To $S_Files2Attach[0] $S_Files2Attach[$x] = _PathFull($S_Files2Attach[$x]);~ ConsoleWrite('@@ Debug : $S_Files2Attach[$x] = ' & $S_Files2Attach[$x] & @LF & '>Error code: ' & @error & @LF) ;### Debug Console If FileExists($S_Files2Attach[$x]) Then ConsoleWrite('+> File attachment added: ' & $S_Files2Attach[$x] & @LF) $objEmail.AddAttachment($S_Files2Attach[$x]) Else ConsoleWrite('!> File not found to attach: ' & $S_Files2Attach[$x] & @LF) SetError(1) Return 0 EndIf Next EndIf $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusing") = 2 $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserver") = $s_SmtpServer If Number($IPPort) = 0 then $IPPort = 25 $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpserverport") = $IPPort ;Authenticated SMTP If $s_Username <> "" Then $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpauthenticate") = 1 $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendusername") = $s_Username $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/sendpassword") = $s_Password EndIf If $ssl Then $objEmail.Configuration.Fields.Item ("http://schemas.microsoft.com/cdo/configuration/smtpusessl") = True EndIf ;Update settings $objEmail.Configuration.Fields.Update ; Set Email Importance Switch $s_Importance Case "High" $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "High" Case "Normal" $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Normal" Case "Low" $objEmail.Fields.Item ("urn:schemas:mailheader:Importance") = "Low" EndSwitch $objEmail.Fields.Update ; Sent the Message $objEmail.Send If @error Then SetError(2) Return $oMyRet[1] EndIf $objEmail=""EndFunc ;==>_INetSmtpMailCom;;; Com Error HandlerFunc MyErrFunc() $HexNumber = Hex($oMyError.number, 8) $oMyRet[0] = $HexNumber $oMyRet[1] = StringStripWS($oMyError.description, 3) ConsoleWrite("### COM Error ! Number: " & $HexNumber & " ScriptLine: " & $oMyError.scriptline & " Description:" & $oMyRet[1] & @LF) SetError(1); something to check for when this function returns Return EndFunc ;==>MyErrFuncThanks for your help Edited October 7, 2014 by ramoyous
jaclaz Posted October 7, 2014 Posted October 7, 2014 There must be something lost in translation. This method:; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error ThenMsgBox(0, "Error sending message", "Error code:" & @error & " Description:" & $rc)EndIfis possibly wrong (and however it seems to me like not needed/prone to issues as soon as the log grows in size). Simply try replacing:If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl) with something *like*:If StringInStr($pageArray[$i], "alarm") Then $Response =MsgBox(0, "Hallo", "I am sending an email" & @error & " Description:" & $i) and see which lines in the log trigger the e-mail sending. (use a short log, with only a few lines, once without any "alarm" in it, once with a single instance of "alarm" in it and one with two or more instances). jaclaz
ramoyous Posted October 7, 2014 Author Posted October 7, 2014 There must be something lost in translation. This method:; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error ThenMsgBox(0, "Error sending message", "Error code:" & @error & " Description:" & $rc)EndIfis possibly wrong (and however it seems to me like not needed/prone to issues as soon as the log grows in size). Simply try replacing:If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl) with something *like*:If StringInStr($pageArray[$i], "alarm") Then $Response =MsgBox(0, "Hallo", "I am sending an email" & @error & " Description:" & $i) and see which lines in the log trigger the e-mail sending. (use a short log, with only a few lines, once without any "alarm" in it, once with a single instance of "alarm" in it and one with two or more instances). jaclaz Thank you Jaclaz for your reply i will try it
ramoyous Posted October 7, 2014 Author Posted October 7, 2014 There must be something lost in translation. This method:; First we read the text file$Log = FileRead($TextFileName); Put the contents into an array$pageArray = StringSplit($Log, @CRLF); Now go through the array and look for the word alarm if its found send and emailGlobal $oMyRet[2]Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc")For $i = 1 To $pageArray[0]If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl)NextIf @error ThenMsgBox(0, "Error sending message", "Error code:" & @error & " Description:" & $rc)EndIfis possibly wrong (and however it seems to me like not needed/prone to issues as soon as the log grows in size). Simply try replacing:If StringInStr($pageArray[$i], "alarm") Then $Response = _INetSmtpMailCom($SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, $Username, $Password, $IPPort, $ssl) with something *like*:If StringInStr($pageArray[$i], "alarm") Then $Response =MsgBox(0, "Hallo", "I am sending an email" & @error & " Description:" & $i) and see which lines in the log trigger the e-mail sending. (use a short log, with only a few lines, once without any "alarm" in it, once with a single instance of "alarm" in it and one with two or more instances). jaclaz When i made this and when running script it print text between () Hallo like title and i am sending an email like text
jaclaz Posted October 8, 2014 Posted October 8, 2014 When i made this and when running script it print text between () Hallo like title and i am sending an email like text Sure, this is expected. The point is that the message box should come up ONLY if the text "alarm" is found in the log, and only as many times as the word "alarm" is found in it. Hence the need to test the script with 3 (three) different logs:containing the word "alarm" only once NOT cotaining the word "alarm" containing the word "alarm" more than once (on different lines)and check if the result is what is expected, i.e.the message box appears once only the message box does NOT appear the message box appears as many times as the word "alarm" is in the logThis is "standard procedure" when developing *any* program/script, you write the code, then test it against "dummy" data, specially crafted to hopefully covering all possibilities, and verify that it works as expected, if it doesn't you go back to the writing and correct/change the code. jaclaz
MHz Posted October 8, 2014 Posted October 8, 2014 Hi ramoyous, I doubt that you would want an separate email sent with each line containing "alarm". Why not send all of the lines in 1 email. StringRegExp() may do the searching for "alarm" in the files content. I have changed the main body of the code and I will not repost the UDFs. You should hopefully understand the start and end markers of where the code is to be inserted.;##################################; Script;##################################; First we read the text file$sLog = FileRead($TextFileName); Search for 'alarm' using PCRE.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sLog, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantenate from the array of matchesFor $i1 = 0 To UBound($aLog) -1 $sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then attempt to send emailIf $sLog Then ; Array used by _INetSmtpMailCom() and MyErrFunc() Global $oMyRet[2] ; Register COM error handler Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; Send email message $Response = _INetSmtpMailCom( _ $SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, _ $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, _ $Username, $Password, $IPPort, $ssl _ ) ; _INetSmtpMailCom() @error check If @error Then MsgBox(0x40030, "Error sending message", _ "Error code:" & @error & " Description:" & $Response _ ) EndIfEndIf;; The UDFAs for the RegEx Test, I used this.#Region Create a test log file; Open a log to write to$hWrite = FileOpen('test.log', 2); Check that the write handle is validIf $hWrite = -1 Then Exit 1; Some test lines added to an arrayDim $lines[3] = [ _ 'Line 1', _ 'Alarm: Something failed.', _ 'Line 3' _]; Write 50 lines in random sequenceFor $i1 = 0 To 50 $iRandom = Random(0, UBound($lines) -1, 1) FileWriteLine('test.log', '[' & $i1 & '] ' & $lines[$iRandom])Next; Close the write handleFileClose($hWrite)#EndRegion#Region Read test log file and find 'alarm'; Read the whole file$sContent = FileRead('test.log'); Search for 'alarm'.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sContent, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantinate from the array of matchesFor $i1 = 0 To UBound($aLog) -1 $sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then send mailIf $sLog Then MsgBox(0, 'Send Mail', $sLog)EndIf#EndRegion; CleanupFileDelete('test.log')HTH
ramoyous Posted October 9, 2014 Author Posted October 9, 2014 When i made this and when running script it print text between () Hallo like title and i am sending an email like text Sure, this is expected. The point is that the message box should come up ONLY if the text "alarm" is found in the log, and only as many times as the word "alarm" is found in it. Hence the need to test the script with 3 (three) different logs:containing the word "alarm" only once NOT cotaining the word "alarm" containing the word "alarm" more than once (on different lines)and check if the result is what is expected, i.e.the message box appears once only the message box does NOT appear the message box appears as many times as the word "alarm" is in the logThis is "standard procedure" when developing *any* program/script, you write the code, then test it against "dummy" data, specially crafted to hopefully covering all possibilities, and verify that it works as expected, if it doesn't you go back to the writing and correct/change the code. jaclaz Hello Jaclaz Thank you very much for your reply and your interest, now i can say that i understood you good, and i'll try this in case and after succesful test i'll change the message box to send mails. Best regards
ramoyous Posted October 9, 2014 Author Posted October 9, 2014 Hi ramoyous, I doubt that you would want an separate email sent with each line containing "alarm". Why not send all of the lines in 1 email. StringRegExp() may do the searching for "alarm" in the files content. I have changed the main body of the code and I will not repost the UDFs. You should hopefully understand the start and end markers of where the code is to be inserted.;##################################; Script;##################################; First we read the text file$sLog = FileRead($TextFileName); Search for 'alarm' using PCRE.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sLog, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantenate from the array of matchesFor $i1 = 0 To UBound($aLog) -1 $sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then attempt to send emailIf $sLog Then ; Array used by _INetSmtpMailCom() and MyErrFunc() Global $oMyRet[2] ; Register COM error handler Global $oMyError = ObjEvent("AutoIt.Error", "MyErrFunc") ; Send email message $Response = _INetSmtpMailCom( _ $SmtpServer, $FromName, $FromAddress, $ToAddress, $Subject, _ $Body, $AttachFiles, $CcAddress, $BccAddress, $Importance, _ $Username, $Password, $IPPort, $ssl _ ) ; _INetSmtpMailCom() @error check If @error Then MsgBox(0x40030, "Error sending message", _ "Error code:" & @error & " Description:" & $Response _ ) EndIfEndIf;; The UDFAs for the RegEx Test, I used this.#Region Create a test log file; Open a log to write to$hWrite = FileOpen('test.log', 2); Check that the write handle is validIf $hWrite = -1 Then Exit 1; Some test lines added to an arrayDim $lines[3] = [ _ 'Line 1', _ 'Alarm: Something failed.', _ 'Line 3' _]; Write 50 lines in random sequenceFor $i1 = 0 To 50 $iRandom = Random(0, UBound($lines) -1, 1) FileWriteLine('test.log', '[' & $i1 & '] ' & $lines[$iRandom])Next; Close the write handleFileClose($hWrite)#EndRegion#Region Read test log file and find 'alarm'; Read the whole file$sContent = FileRead('test.log'); Search for 'alarm'.; Pattern. eol = CRLF, multiline mode, case insensitive, _; word breaks around 'alarm', ^ = start of line, $ = end of line$aLog = StringRegExp($sContent, '(*CRLF)(?mi)^.*\bAlarm\b.*$', 3)$sLog = ''; Concantinate from the array of matchesFor $i1 = 0 To UBound($aLog) -1 $sLog &= $aLog[$i1] & @CRLFNext; If $sLog is something, then send mailIf $sLog Then MsgBox(0, 'Send Mail', $sLog)EndIf#EndRegion; CleanupFileDelete('test.log')HTH Hello dear MHz, Thank you for your reply, and for the work you made, God blessed you, so i will try that and i'll inform you for the result Best regards
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