Jump to content

Auto Close Idle Application


Recommended Posts

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

Link to comment
Share on other sites

  • 2 weeks later...

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

Link to comment
Share on other sites

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

Link to comment
Share on other sites

#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 by InunoTaishou
Added some more comments
Link to comment
Share on other sites

On 3/23/2017 at 0:01 PM, InunoTaishou said:
#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

Link to comment
Share on other sites

  • 1 year later...
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 by dmob
Link to comment
Share on other sites

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?

Link to comment
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
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...