jaycee73 Posted March 8, 2017 Posted March 8, 2017 Hi all, I'm using the below script (that I found elsewhere and modified) to detect an idle application and auto logoff if it has been idle for a certain amount of time. It works perfectly when there is only one instance of the application open, but what I would like, if possible, is if it can also detect a second instance that is idle in the background while a user is actively using the first instance - at the moment if one instance is active then the second, idle instance, is not closed. Both instances of my application have identical titles. Thanks in advance for any assistance, John #cs ---------------------------------------------------------------------------- AutoIt Version: 3.3.14.2 Author: Script Function: Auto logs out inactive applicationXXX Sessions #ce ---------------------------------------------------------------------------- ; Script Start - Add your code below here Opt("WinTitleMatchMode", 2) ;3 = exact title match Opt("TrayIconDebug", 1) ; Opt("TrayIconHide", 1) $S_running = "check-4-app" ;name the script If WinExists($S_running) Then Exit AutoItWinSetTitle($S_running) $title = "applicationXXX" $count = 0 While 1 $state = WinGetState($title) $count += 1 If $state = 15 Or $state = 47 Or $state = 0 Or $state = 3 Or $state = 7 Then $count = 0 If $count > 20 Then WinClose($title) ToolTip("count = " & $count, 0, 0, "state = " & $state) Sleep(1000) WEnd
JohnOne Posted March 9, 2017 Posted March 9, 2017 Well for a start, you should work with handles rather than titles. But first, define "Idle Application" AutoIt Absolute Beginners Require a serial Pause Script Video Tutorials by Morthawt ipify Monkey's are, like, natures humans.
Juvigy Posted March 10, 2017 Posted March 10, 2017 Check the functions ProcessExists, ProcessList, ProcessClose
jaycee73 Posted March 22, 2017 Author Posted March 22, 2017 Thanks for your responses JohnOne and Juvigy. Unfortunately, I'm not a programmer (just a bit of a hack) so don't have the skills to rewrite the script from scratch. Any other advice would be appreciated. Cheers, Jaycee
jaycee73 Posted March 22, 2017 Author Posted March 22, 2017 On 3/10/2017 at 4:15 AM, JohnOne said: Well for a start, you should work with handles rather than titles. But first, define "Idle Application" In this instance, the application window has not been interacted with in x amount of time (i.e. the user is either away from their desk, or busy using a different application. Cheers, Jaycee
InunoTaishou Posted March 23, 2017 Posted March 23, 2017 (edited) expandcollapse popup#include <Array.au3> Opt("WinTitleMatchMode", 2) ;3 = exact title match Opt("TrayIconDebug", 1) ; Opt("TrayIconHide", 1) Global Const $ARRAY_HANDLE = 0 Global Const $ARRAY_PID = 1 Global Const $ARRAY_COUNT = 2 Global Const $WINLIST_TITLE = 0 Global Const $WINLIST_HANDLE = 1 Global $aWindows[0][3] For $i = 0 to 3 Run("notepad.exe", @SystemDir) Next $title = "Untitled - Notepad" $S_running = "check-4-app" ;name the script UpdateWithHandles($aWindows, $title) If WinExists($S_running) Then Exit AutoItWinSetTitle($S_running) While (True) Local $sToolTip = "" For $i = UBound($aWindows) -1 to 0 Step -1 $state = WinGetState($aWindows[$i][$ARRAY_HANDLE]) $aWindows[$i][$ARRAY_COUNT] += 1 If ($state = 15 Or $state = 47 Or $state = 0 Or $state = 3 Or $state = 7) Then $aWindows[$i][$ARRAY_COUNT] = 0 EndIf If ($aWindows[$i][$ARRAY_COUNT] > 20) Then WinClose($aWindows[$i][$ARRAY_HANDLE]) $sToolTip &= $aWindows[$i][$ARRAY_HANDLE] & ":" & @CRLF & @TAB & "Count = " & $aWindows[$i][$ARRAY_COUNT] & @CRLF & @TAB & "State = " & $state & @CRLF Next ToolTip(StringTrimRight($sToolTip, 2), 0, 0) Sleep(1000) UpdateWithHandles($aWindows, $title) WEnd Func UpdateWithHandles(ByRef $aArray, Const ByRef $sWindowTitle) Local $aWinList = WinList() ; My personal preference, hate having the count in the first element of an array, so I remove it _ArrayDelete($aWinList, 0) If (UBound($aArray)) Then ; First check that the window still exists, if it doesn't then remove it For $iProcess = UBound($aArray) - 1 to 0 Step - 1 If (Not WinExists($aArray[$iProcess][$ARRAY_HANDLE])) Then ; Window no longer exists, remove from the array _ArrayDelete($aArray, $iProcess) EndIf Next EndIf For $iProcess = 0 To UBound($aWinList) -1 Local $iPid = 0 Local $iIndex = 0 ; Title of this window is the title we're looking for If ($aWinList[$iProcess][$WINLIST_TITLE] = $sWindowTitle) Then ; I used PID but you can use the handle, just wanted to throw PID in this script $iPid = WinGetProcess($aWinList[$iProcess][$WINLIST_HANDLE]) If (_ArraySearch($aArray, $iPid, 0, 0, 0, 0, 1, $ARRAY_PID) = -1) Then ; Store the current index so we don't have to use UBound 4 times $iIndex = UBound($aArray) ; Redim the array so we can add the new handle, PID, and count ReDim $aArray[$iIndex + 1][UBound($aArray, $UBOUND_COLUMNS)] ; Add values $aArray[$iIndex][$ARRAY_HANDLE] = $aWinList[$iProcess][$WINLIST_HANDLE] $aArray[$iIndex][$ARRAY_PID] = $iPid $aArray[$iIndex][$ARRAY_COUNT] = 0 EndIf EndIf Next EndFunc Give that a go. I cleaned up some of the code, not all. You should rework the state checking to only reset to 0 when the window is visible and active. This can be more easily accomplished using BitAND If (BitAND($state, 8) and BitAND($state, 2)) Then ... EndIf It's up to you how you want to determine if a window is inactive though, just my preference. Edited March 23, 2017 by InunoTaishou Added some more comments
jaycee73 Posted March 24, 2017 Author Posted March 24, 2017 On 3/23/2017 at 0:01 PM, InunoTaishou said: expandcollapse popup#include <Array.au3> Opt("WinTitleMatchMode", 2) ;3 = exact title match Opt("TrayIconDebug", 1) ; Opt("TrayIconHide", 1) Global Const $ARRAY_HANDLE = 0 Global Const $ARRAY_PID = 1 Global Const $ARRAY_COUNT = 2 Global Const $WINLIST_TITLE = 0 Global Const $WINLIST_HANDLE = 1 Global $aWindows[0][3] For $i = 0 to 3 Run("notepad.exe", @SystemDir) Next $title = "Untitled - Notepad" $S_running = "check-4-app" ;name the script UpdateWithHandles($aWindows, $title) If WinExists($S_running) Then Exit AutoItWinSetTitle($S_running) While (True) Local $sToolTip = "" For $i = UBound($aWindows) -1 to 0 Step -1 $state = WinGetState($aWindows[$i][$ARRAY_HANDLE]) $aWindows[$i][$ARRAY_COUNT] += 1 If ($state = 15 Or $state = 47 Or $state = 0 Or $state = 3 Or $state = 7) Then $aWindows[$i][$ARRAY_COUNT] = 0 EndIf If ($aWindows[$i][$ARRAY_COUNT] > 20) Then WinClose($aWindows[$i][$ARRAY_HANDLE]) $sToolTip &= $aWindows[$i][$ARRAY_HANDLE] & ":" & @CRLF & @TAB & "Count = " & $aWindows[$i][$ARRAY_COUNT] & @CRLF & @TAB & "State = " & $state & @CRLF Next ToolTip(StringTrimRight($sToolTip, 2), 0, 0) Sleep(1000) UpdateWithHandles($aWindows, $title) WEnd Func UpdateWithHandles(ByRef $aArray, Const ByRef $sWindowTitle) Local $aWinList = WinList() ; My personal preference, hate having the count in the first element of an array, so I remove it _ArrayDelete($aWinList, 0) If (UBound($aArray)) Then ; First check that the window still exists, if it doesn't then remove it For $iProcess = UBound($aArray) - 1 to 0 Step - 1 If (Not WinExists($aArray[$iProcess][$ARRAY_HANDLE])) Then ; Window no longer exists, remove from the array _ArrayDelete($aArray, $iProcess) EndIf Next EndIf For $iProcess = 0 To UBound($aWinList) -1 Local $iPid = 0 Local $iIndex = 0 ; Title of this window is the title we're looking for If ($aWinList[$iProcess][$WINLIST_TITLE] = $sWindowTitle) Then ; I used PID but you can use the handle, just wanted to throw PID in this script $iPid = WinGetProcess($aWinList[$iProcess][$WINLIST_HANDLE]) If (_ArraySearch($aArray, $iPid, 0, 0, 0, 0, 1, $ARRAY_PID) = -1) Then ; Store the current index so we don't have to use UBound 4 times $iIndex = UBound($aArray) ; Redim the array so we can add the new handle, PID, and count ReDim $aArray[$iIndex + 1][UBound($aArray, $UBOUND_COLUMNS)] ; Add values $aArray[$iIndex][$ARRAY_HANDLE] = $aWinList[$iProcess][$WINLIST_HANDLE] $aArray[$iIndex][$ARRAY_PID] = $iPid $aArray[$iIndex][$ARRAY_COUNT] = 0 EndIf EndIf Next EndFunc Give that a go. I cleaned up some of the code, not all. You should rework the state checking to only reset to 0 when the window is visible and active. This can be more easily accomplished using BitAND If (BitAND($state, 8) and BitAND($state, 2)) Then ... EndIf It's up to you how you want to determine if a window is inactive though, just my preference. Thanks so much InunoTaishou - that does exactly what I need it to. I'll have a play with BitAnd, but for the moment I've just added all the various windows states used by my application in the status check. Regards, Jaycee
RedAck Posted February 21, 2019 Posted February 21, 2019 is it possible to monitor idle time for more than 1 application?
dmob Posted February 21, 2019 Posted February 21, 2019 (edited) 40 minutes ago, RedAck said: is it possible to monitor idle time for more than 1 application? Should be easy enough to attempt, edit the code in this section: ; Title of this window is the title we're looking for Edited February 21, 2019 by dmob
RedAck Posted February 21, 2019 Posted February 21, 2019 2 hours ago, dmob said: Should be easy enough to attempt, edit the code in this section: ; Title of this window is the title we're looking for I'm not that good at autoit and just started to explore autoit. This topic was interesting and wanted to explore more on this. lets say if i want to monitor notepad, word and excel... how to write the script? what if all three application are minimised? in which order the script works?
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