Icarus Posted October 29, 2008 Share Posted October 29, 2008 Hi,I am using Winlist () to capture window titles, and then screen dump known error messages.This is working fine. What I need to do, though, is also make a cumulative list of Window Titles, with a time / date stamp.I can do this in shell script. I need an efficient routine in AutoIt to replace, and I'm really struggling.. Please can someone assist?This is my shell script that needs a better Autoit routine:@echo offset file=%1 ;this is a list of (duplicate) windows in a text file. Its the same as running Winlist () over and over and dumping to a text file.set out=Windows.txt ;this is my cumulative listfor /f "tokens=*" %%a in ('sort %file%') do type %out%|find "%%a" || echo %date%;%time%;%%a>>%out%The output looks like this:22/10/2008;17:35:55.54;Complaint - Cust Serv. - Message (Rich Text) 22/10/2008;17:35:55.54;New Note22/10/2008;17:35:55.54;Untitled - Note 22/10/2008;17:36:22.62;Tasks22/10/2008;18:58:20.65;Please wait...Its very inefficient to type the whole file out again and again looking for known windows, and then echoing those not (using the double || lines) found.Your help and time is very much apprecaited. Link to comment Share on other sites More sharing options...
weaponx Posted October 29, 2008 Share Posted October 29, 2008 #include <file.au3> $log = @ScriptDir & "\my.log" $array = WinList() For $X = 1 to $array[0][0] _FileWriteLog($log,$array[$X][0]) Next Link to comment Share on other sites More sharing options...
komalo Posted October 29, 2008 Share Posted October 29, 2008 (edited) try this $WinList = WinList() $WindowsLog = @ScriptDir & "\Windows.txt" For $i = 1 to $WinList[0][0] If $WinList[$i][0] <> "" AND IsVisible($WinList[$i][1]) Then FileWrite($WindowsLog,GetCurrent() & " " & $WinList[$i][0] & @CRLF) EndIf Next Func IsVisible($handle) If BitAnd( WinGetState($handle), 2 ) Then Return 1 Return 0 EndFunc Func GetCurrent() $Time = @HOUR & ":" & @MIN & ":" & @SEC $Date = @YDAY & ":" & @MON & ":" & @YEAR $Return = $Date & ";" & $Time & " " Return $Return EndFunc Edited October 29, 2008 by komalo [font="Palatino Linotype"][size="3"]AutoIt Script Examples :[/size][/font][font="Palatino Linotype"][size="3"]_CaptureBehindWindowGlass CMD for Windows Vista/Seven[/size][/font][left][/left][font="Palatino Linotype"][size="3"]Non AutoIt Script programs : Border Skin - Aero Glass On XP[/size][/font] Link to comment Share on other sites More sharing options...
Icarus Posted November 4, 2008 Author Share Posted November 4, 2008 Thank you for the responses - I'll test them and let you know. Much appreciated!! Icarus Link to comment Share on other sites More sharing options...
Icarus Posted November 4, 2008 Author Share Posted November 4, 2008 try this $WinList = WinList() $WindowsLog = @ScriptDir & "\Windows.txt" For $i = 1 to $WinList[0][0] If $WinList[$i][0] <> "" AND IsVisible($WinList[$i][1]) Then FileWrite($WindowsLog,GetCurrent() & " " & $WinList[$i][0] & @CRLF) EndIf Next Func IsVisible($handle) If BitAnd( WinGetState($handle), 2 ) Then Return 1 Return 0 EndFunc Func GetCurrent() $Time = @HOUR & ":" & @MIN & ":" & @SEC $Date = @YDAY & ":" & @MON & ":" & @YEAR $Return = $Date & ";" & $Time & " " Return $Return EndFunc Komalo, This is spot on, thank you, as I really need the date and time, just as you've done it. The only problem I have now, is that when I run it again and again, I end up with Windows.txt getting bigger and bigger. I need it to grow with each UNIQUE window title. If I read back the contents of Windows.txt, and compare it to the WINLIST () array, every line is unique because of the date and time stamp. Is it possible to 1) Read the WINDOWS.TXT file and COMPARE this to the current window list (without the date / time stamp) 2) Output unique Window lists Its getting at the Window title in the WINDOWS.TXT file that I can't do, as its bringing back the date / time stamp too. Thanks so much. Its really really helpful. Icarus. Link to comment Share on other sites More sharing options...
Icarus Posted November 4, 2008 Author Share Posted November 4, 2008 (edited) Aim of project - To gradually build up a list of uinique window titles, including the date and time stamp when they first appear, and to optionally do something if one of the window titles matches a list of error words (in errors.txt) such as "not responding". Here is my code so far: expandcollapse popupOpt("TrayIconHide", 1) ;0=show, 1=hide tray icon #include <Array.au3> Local $avArray[1] ;Open a file for writing: $file = FileOpen("windows.txt", 2) $file2 = FileOpen("errors.txt", 0) ; Check if file opened for reading OK If $file2 = -1 Then ConsoleWrite ("Error", "Unable to open file.") Exit EndIf ; Check if file opened for writing OK If $file = -1 Then ConsoleWrite ("Error", "Unable to open file.") Exit EndIf ; Read in lines of text until the EOF is reached While 1 $line = FileReadLine($file2) If @error = -1 Then ExitLoop ; MsgBox(0, "Line read:", $errors) ;Get window list $var = WinList() For $i = 1 to $var[0][0] ; Only display visble windows that have a title If $var[$i][0] <> "" AND IsVisible($var[$i][1]) Then ;dump these window titles to a file (Windows.txt) $iIndex = _ArraySearch($avArray, $var[$i][0], 0, 0, 0, 1) If @error Then _ArrayAdd($avArray, $var[$i][0]) FileWriteLine($file, $var[$i][0] & @CRLF) Else ;MsgBox(0, "Found", '"' & $sSearch & '" was found in the array at position ' & $iIndex & ".") EndIf ;if an error string is found, then do something here: $found=(StringRegExp($var[$i][0], $line)) if ($found >0) Then ;ConsoleWrite ($var[$i][0] & @LF) EndIf EndIf Next Wend ;_ArrayDisplay($avArray, "$avArray AFTER _ArrayAdd()") FileClose($file) FileClose($file2) ;Sleep(1000) Func IsVisible($handle) If BitAnd( WinGetState($handle), 2 ) Then Return 1 Else Return 0 EndIf EndFunc Edited November 4, 2008 by Icarus Link to comment Share on other sites More sharing options...
LarryDalooza Posted November 4, 2008 Share Posted November 4, 2008 Also a WH_CBT hook will report window creations. It can be done in AutoIt natively or through my hook.dll. Search the forum well for hooks... but try not to ask too many questions about hooks. Hooks are the technology behind some of the badder viruses. ... I mean more badder. Lar. AutoIt has helped make me wealthy Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 4, 2008 Share Posted November 4, 2008 I like this version because it detects by handles, so it will log if the same window keeps popping up, but never logs multiple hits for the same instance of a window. I would use post-processing of the log to pull unique titles, but you could add a test to the loop very easily: expandcollapse popup#include <File.au3> #include <Array.au3> HotKeySet("{ESC}", "_Quit") ; Initialize log file, make sure it's writeable Global $sLogFile = "C:\Temp\WinLog.log" Global $hLogFile = FileOpen($sLogFile, 1); Write, append If $hLogFile = -1 Then MsgBox(16, "Error", "Failed to open file for write: " & $sLogFile) Exit EndIf FileWriteLine($hLogFile, @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & _ " : Started window monitor script."); Timestamp matches _FileWriteLog format FileClose($hLogFile) ; Initialize tracking arrays Global $avWinListPrevious[1][2] = [[0, ""]], $avWinListCurrent ; Monitor unique window handles While 1 $avWinListCurrent = WinList() For $n = $avWinListCurrent[0][0] To 1 Step -1 ; Check has title and visible If ($avWinListCurrent[$n][0] <> "") And BitAND(WinGetState($avWinListCurrent[$n][1]), 2) Then ; Check for already seen $fFound = False For $i = 1 To $avWinListPrevious[0][0] If $avWinListCurrent[$n][1] = $avWinListPrevious[$i][1] Then $fFound = True ExitLoop EndIf Next ; New window found If Not $fFound Then _FileWriteLog($sLogFile, "New window detected: hWnd: " & $avWinListCurrent[$n][1] & _ " Title: " & $avWinListCurrent[$n][0]) EndIf Else _ArrayDelete($avWinListCurrent, $n) EndIf Next $avWinListCurrent[0][0] = UBound($avWinListCurrent) - 1 $avWinListPrevious = $avWinListCurrent Sleep(500) WEnd Func _Quit() Exit EndFunc ;==>_Quit 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...
PsaltyDS Posted November 4, 2008 Share Posted November 4, 2008 (edited) Hooks are the technology behind some of the badder viruses.Hooks and bladder viruses; it all sounds so painful... oh, wait... Edited November 4, 2008 by PsaltyDS 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...
komalo Posted November 4, 2008 Share Posted November 4, 2008 Aim of project1 - gradually build up a list of uinique window titles, including the date and time stamp when they first appear 2 - optionally do something if one of the window titles matches a list of error words (in errors.txt) here it is with shellhooking ( this is a big modification of ShellHookWindow ) expandcollapse popup#NoTrayIcon #include <Misc.au3> #include <WinAPI.au3> Global Const $HSHELL_WINDOWCREATED = 1 Global $WinLog = @ScriptDir & "\Windows Log.txt" Global $Error = @ScriptDir & "\Error.txt" If FileExists($WinLog) Then FileDelete($WinLog) $WinError = FileRead($Error) HotKeySet("{ESC}","Close") $hGui = GUICreate("", 0, 0, 0, 0) GUIRegisterMsg(_WinAPI_RegisterWindowMessage("SHELLHOOK"), "HShellWndProc") ShellHookWindow($hGui, 1) WriteToLog("Monitering Started") While 1 Sleep(1000) WEnd Func Close() ShellHookWindow($hGui, 0) WriteToLog("Monitering Ended") Exit EndFunc Func HShellWndProc($hWnd, $Msg, $wParam, $lParam) Switch $wParam Case $HSHELL_WINDOWCREATED WriteToLog(" New Window: " & $lParam & " (" & WinGetTitle($lParam) & ")") EndSwitch EndFunc Func WriteToLog($sText) If ComareError($sText) Then MsgBox("","Exists in Error", "The " & $sText & " is Detected At Error Text") FileWriteLine($WinLog,GetCurrent() & $sText) EndFunc Func ComareError($sText) If StringInStr($sText,$WinError) Then Return True Return False EndFunc Func ShellHookWindow($hWnd, $bFlag) Local $sFunc = 'DeregisterShellHookWindow' If $bFlag Then $sFunc = 'RegisterShellHookWindow' Local $aRet = DllCall('user32.dll', 'int', $sFunc, 'hwnd', $hWnd) WriteToLog($sFunc & ' = ' & $aRet[0]) Return $aRet[0] EndFunc Func GetCurrent() $Time = @HOUR & ":" & @MIN & ":" & @SEC $Date = @MDAY & "-" & @MON & "-" & @YEAR $Return = $Date & " " & $Time & " " Return $Return EndFunc [font="Palatino Linotype"][size="3"]AutoIt Script Examples :[/size][/font][font="Palatino Linotype"][size="3"]_CaptureBehindWindowGlass CMD for Windows Vista/Seven[/size][/font][left][/left][font="Palatino Linotype"][size="3"]Non AutoIt Script programs : Border Skin - Aero Glass On XP[/size][/font] Link to comment Share on other sites More sharing options...
Icarus Posted November 6, 2008 Author Share Posted November 6, 2008 Thankx to you all - Weaponx - nice, and simple - I can understand that. Cheers.Komalo - Thanks for both your post too - especially the shell hook stuff. That was a little over my head, but I'm reading through it slowly to try and understand..PsaltyDS - WOW! - Your code example is great. The handle grabbing is just what I was after, as now when a new handle is found, I can grab a screenshot using:; Capture window _ScreenCapture_CaptureWnd (@MyDocumentsDir & $avWinListCurrent[$n][0] & ".jpg", $avWinListCurrent[$n][1])As this stands, my project is nearly there. It is capturing window titles, and logging them with date / time stamps. When a new window is found it takes a screenshot of that window.The final piece of the jigsaw is to have it screen grab specific windows based on a list of key words.I was thinking that I would pre-load an array of words like this:Global $avErrorlist[1]=["error"]And then do a comparison of the window title:if $avWinListCurrent[$n][0] = $avErrorlist[1] then ;Capture window.Since I want to compile this to a .exe for deployment, it probably not a good idea to have hard-coded error lists within the app.Any suggestions of where to store / add these would be very welcome, or a better way to do the window comparison. Finally, I'd like to ensure I can compare long text names with spaces too, eg : "Task Manager".Once again, a HUGE thank you to the skills and coding examples shown here. You guys are amazing..Icarus. Link to comment Share on other sites More sharing options...
Icarus Posted November 6, 2008 Author Share Posted November 6, 2008 ...just realised that komalo has got some error checking in that code example - hadn't spotted that. Checking that out now.. cheers again... Link to comment Share on other sites More sharing options...
Icarus Posted November 6, 2008 Author Share Posted November 6, 2008 OK. Still struggling with finding the errors from the error file (error.txt) in the window lists.It works if I put an EXACT copy of a window title in.I've switched the parameters round to help highlight this:Global $Error = @ScriptDir & "\Error.txt" $WinError = FileRead($Error) Func CompareError($sText) If StringInStr($WinError, $sText) Then Return True Return False EndFuncDo {any of the words in this text file : error.txt} match {any part of the current window title, $stext)Please can I ask for a little more input?Cheers.... Link to comment Share on other sites More sharing options...
Icarus Posted November 6, 2008 Author Share Posted November 6, 2008 I've tried to break this down into just reading the list of error codes into the array, and passing it a dummy window handle ($sText): Global $Error = @ScriptDir & "\Error.txt" #Include <Array.au3> #include <file.au3> Dim $aRecords ;Read the file into an array If Not _FileReadToArray($Error,$aRecords) Then MsgBox(4096,"Error", " Error reading log to Array error:" & @error) Exit EndIf ;Function to compare each word in Error.txt with the current window title and return TRUE if any match Func CompareError($sText) For $x = 1 to $aRecords[0] ConsoleWrite ($aRecords[$x] & @LF) If StringInStr($aRecords[$x], $sText) Then Return True Return False Next EndFunc ;Dummy window title $sText="Windows Task Manager" If CompareError($sText) then ConsoleWrite ("Matched" & $sText & @LF) This code doesn't return anything, even when there is only one word, "Task", in error.txt Icarus Link to comment Share on other sites More sharing options...
PsaltyDS Posted November 6, 2008 Share Posted November 6, 2008 I've tried to break this down into just reading the list of error codes into the array, and passing it a dummy window handle ($sText): ; ... ;Function to compare each word in Error.txt with the current window title and return TRUE if any match Func CompareError($sText) For $x = 1 to $aRecords[0] ConsoleWrite ($aRecords[$x] & @LF) If StringInStr($aRecords[$x], $sText) Then Return True Return False Next EndFunc ;... This code doesn't return anything, even when there is only one word, "Task", in error.txt Icarus You've got your parameters bassackwards: StringInStr($sText, $aRecords[$x]) 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...
Icarus Posted November 10, 2008 Author Share Posted November 10, 2008 Final thanks to everyone. I now have a small application that when running, sits in the background waiting for error messages (in error.txt). When these are found, it takes a snapshot of the window for future investigation. It can be any words in error.txt ("error", "unable", "failed" etc.) Many many thanks to all who helped. Final code here for anyone who might find it helpful: expandcollapse popup#include <File.au3> #include <Array.au3> #include <ScreenCapture.au3> Global $Error = @ScriptDir & "\Error.txt" $WinError = FileRead($Error) Dim $aRecords If Not _FileReadToArray($Error,$aRecords) Then MsgBox(4096,"Error", " Error reading log to Array error:" & @error) Exit EndIf Opt("TrayIconHide", 1) ;0=show, 1=hide tray icon HotKeySet("^!q", "_Quit");Control+Alt+Q to exit the program ; Initialize log file, make sure it's writeable Global $sLogFile = "C:\Temp\WinLog.log" Global $hLogFile = FileOpen($sLogFile, 1); Write, append If $hLogFile = -1 Then MsgBox(16, "Error", "Failed to open file for write: " & $sLogFile) Exit EndIf FileWriteLine($hLogFile, @YEAR & "-" & @MON & "-" & @MDAY & " " & @HOUR & ":" & @MIN & ":" & @SEC & _ " : Started window monitor script."); Timestamp matches _FileWriteLog format FileClose($hLogFile) ; Initialize tracking arrays Global $avWinListPrevious[1][2] = [[0, ""]], $avWinListCurrent ; Initialize error tracking array ; Monitor unique window handles While 1 $avWinListCurrent = WinList() For $n = $avWinListCurrent[0][0] To 1 Step -1 ; Check has title and visible If ($avWinListCurrent[$n][0] <> "") And BitAND(WinGetState($avWinListCurrent[$n][1]), 2) Then ; Check for already seen $fFound = False For $i = 1 To $avWinListPrevious[0][0] If $avWinListCurrent[$n][1] = $avWinListPrevious[$i][1] Then $fFound = True ExitLoop EndIf Next ; New window found If Not $fFound Then _FileWriteLog($sLogFile, "New window detected: hWnd: " & $avWinListCurrent[$n][1] & _ " Title: " & $avWinListCurrent[$n][0]) _FileWriteLog ($sLogfile,"Debug: " & $avWinListCurrent[$n][0]) ; Check for error window titles, and if found, capture window If CompareError($avWinListCurrent[$n][0]) Then _ScreenCapture_CaptureWnd (@MyDocumentsDir & $avWinListCurrent[$n][0] & ".jpg", $avWinListCurrent[$n][1]) EndIf Else _ArrayDelete($avWinListCurrent, $n) EndIf Next $avWinListCurrent[0][0] = UBound($avWinListCurrent) - 1 $avWinListPrevious = $avWinListCurrent Sleep(500) WEnd Func _Quit() Exit EndFunc ;==>_Quit Func CompareError($sText) ;Return False For $x = 1 to $aRecords[0] ;ConsoleWrite ($aRecords[$x] & @LF) If StringInStr($sText, $aRecords[$x]) Then Return True Next EndFunc 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