Jump to content

Autoclose Windows Application after 45 Minutes of inactivity


Recommended Posts

I would to know how create a Script to do the following.

We have a windows Application and would like Autoit close the program after 45 minutes of inactivity, but before close the program generate a popup with the following message

"You have been idle for more than 45 Minutes, Program will close in 5 Seconds.

I would like to use the program title.

 

Thanks

Link to comment
Share on other sites

You can try something like the following:

#include <Array.au3>
#include <Timers.au3>
#include <WinAPIProc.au3>
Global $sProductFilePath = @WindowsDir
Global $sProductFileName = "Notepad.exe"
Global $sProductName = FileGetVersion($sProductFilePath & "\" & $sProductFileName, "ProductName")
Global $hProcessWnd, $aProcessList, $idMsgBox
Global $iTimerInit = TimerInit()
Global $iIdleTime = _Timer_GetIdleTime()
While 1
    $aProcessList = ProcessList($sProductFileName)
    If $aProcessList[0][0] >= 2 Then
        $idMsgBox = MsgBox(48, $sProductName, "Multiple Licenses Detected" & @CRLF & @CRLF & "Due to license limitations only one copy of " & $sProductName & " is allowed." & @CRLF & @CRLF & "Please close additional copies of " & $sProductName)
        $iTimerInit = TimerInit()
        ContinueLoop
    EndIf
    $iProcessId = ProcessExists($sProductFileName)
    If $iProcessId Then
        $iIdleTime = _Timer_GetIdleTime()
        $hProcessWnd = _GetHwndFromPID($iProcessId)
        If WinActive($hProcessWnd ) Then
            $iTimerInit = TimerInit()
        EndIf
        ;~ If the timer is more than 40 minutes then send message to user and close the process, otherwise it closes within 5 minutes
        If TimerDiff($iTimerInit) >= 40 * 60 * 1000 Or $iIdleTime >= 40 * 60 * 1000 Then
            $idMsgBox = MsgBox(48, $sProductName, $sProductName & " has been idle for more than 40 minutes and will be closed in 5 minutes if no activity is detected.", 300)
            If $idMsgBox = -1 Then ProcessClose($sProductFileName)
        EndIf
    EndIf
    Sleep(100)
WEnd

;Function for getting HWND from PID
Func _GetHwndFromPID($_iProcessId)
    Local $_hProcessWnd
    Local $iWinList, $_aWinList = WinList()
    For $i = 1 To $_aWinList[0][0]
        If $_aWinList[$i][0] <> "" Then
            $iWinList = WinGetProcess($_aWinList[$i][1])
            If $iWinList = $_iProcessId Then
                $_hProcessWnd = $_aWinList[$i][1]
                ExitLoop
            EndIf
        EndIf
    Next
    Return $_hProcessWnd
EndFunc;==>_GetHwndFromPID

 

Link to comment
Share on other sites

Strange because it should stay open for 5 minutes (300 seconds), is it disappearing behind a Window?  You may need to add Top Most to the MsgBox i.e.

$idMsgBox = MsgBox(262144 + 48, $sProductName, $sProductName & " has been idle for more than 40 minutes and will be closed in 5 minutes if no activity is detected.", 300)

Assuming this is the MsgBox your referring to and not the Multiple Licenses Detected MsgBox.

Link to comment
Share on other sites

Subz,

 

I double Checked and even minimized everthing and the popup appear for less of 2 seconds and then disappear after closing the notepad. i applied the change you suggested but not luck.

I tried also to run with a different program i have installed but this time the script doesn't close the app.

is possible use a different parameter like the title or the Class?

 

any help will be appreciated.

 

Thanks

 

Link to comment
Share on other sites

Can you tell me what the results of the script below are?  I've set it to 10 seconds for testing, I've also changed it from notepad.exe to cmd.exe, couple of other notes:

TimerInit checks if the Window is active
_Timer_GetIdleTime checks how long the machine has been idle, since a Window can still be "Active" even if your AFK.

Anyway the code below works fine for me, I used something similar a while ago before we moved to a license management system that handles this internally.  I'm not sure why the software wouldn't close for you, I've tried with a few different products and they all close for me, so thought I'd change it to cmd.exe to see if you get the same results.

#include <Array.au3>
#include <Timers.au3>
#include <WinAPIProc.au3>
Global $sProductFilePath = @SystemDir
Global $sProductFileName = "CMD.exe"
Global $sProductName = FileGetVersion($sProductFilePath & "\" & $sProductFileName, "ProductName")
Global $hProcessWnd, $aProcessList, $idMsgBox
Global $iTimerInit = TimerInit()
Global $iIdleTime = _Timer_GetIdleTime()
While 1
    $aProcessList = ProcessList($sProductFileName)
    If $aProcessList[0][0] >= 2 Then
        MsgBox(48, $sProductName, "Multiple Licenses Detected" & @CRLF & @CRLF & "Due to license limitations only one copy of " & $sProductName & " is allowed." & @CRLF & @CRLF & "Please close additional copies of " & $sProductName)
        $iTimerInit = TimerInit()
        $iIdleTime = _Timer_GetIdleTime()
        ContinueLoop
    EndIf
    $iProcessId = ProcessExists($sProductFileName)
    If $iProcessId Then
        $hProcessWnd = _GetHwndFromPID($iProcessId)
        If WinActive($hProcessWnd) Then
            $iTimerInit = TimerInit()
            $iIdleTime = _Timer_GetIdleTime()
        EndIf
        ;~ If the timer is more than 40 minutes then send message to user and close the process, otherwise it closes within 5 minutes
        If TimerDiff($iTimerInit) >= 10 * 1000 Or $iIdleTime >= 10 * 1000 Then
            $idMsgBox = MsgBox(48, $sProductName, $sProductName & " has been idle for more than 40 minutes and will be closed in 5 minutes if no activity is detected.", 10)
            If $idMsgBox = -1 Then ProcessClose($sProductFileName)
        EndIf
    EndIf
    Sleep(100)
WEnd

;Function for getting HWND from PID
Func _GetHwndFromPID($_iProcessId)
    Local $_hProcessWnd
    Local $iWinList, $_aWinList = WinList()
    For $i = 1 To $_aWinList[0][0]
        If $_aWinList[$i][0] <> "" Then
            $iWinList = WinGetProcess($_aWinList[$i][1])
            If $iWinList = $_iProcessId Then
                $_hProcessWnd = $_aWinList[$i][1]
                ExitLoop
            EndIf
        EndIf
    Next
    Return $_hProcessWnd
EndFunc;==>_GetHwndFromPID

 

Link to comment
Share on other sites

  • 3 weeks later...

Hi Subz, 

Great script. I've tested it and it works great. I have a problem with it in my environment:

I use a VM and several people connect remote desktop to it and so if the script is run by me it will also close off other peoples processes... this is not necessarily a bad thing but I would like to pass the pop-up error messages to their screen also. Do you have any clue on how to do that?

Regards,
Silviu

Link to comment
Share on other sites

you could start a new thread instead of feeding off an old one with your new "issue" which is not related to this script at all. You want to send windows messages to rdp users. Did you do a google search for an RDP UDF in autoit? I just searched and there does not look like any. You will have to learn about how to do this in Windows and then try to automate that process.

Edited by Earthshine

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

AFIK you can do this from autoit app, from a command line.

msg * /SERVER:server_name Message goes here

and that will message everyone on that server when it happens. I am assuming this VM is a server with several users connected?

My resources are limited. You must ask the right questions

 

Link to comment
Share on other sites

  • 1 year later...
On 4/26/2018 at 1:46 PM, Subz said:

Can you tell me what the results of the script below are?  I've set it to 10 seconds for testing, I've also changed it from notepad.exe to cmd.exe, couple of other notes:

TimerInit checks if the Window is active
_Timer_GetIdleTime checks how long the machine has been idle, since a Window can still be "Active" even if your AFK.

Anyway the code below works fine for me, I used something similar a while ago before we moved to a license management system that handles this internally.  I'm not sure why the software wouldn't close for you, I've tried with a few different products and they all close for me, so thought I'd change it to cmd.exe to see if you get the same results.

#include <Array.au3>
#include <Timers.au3>
#include <WinAPIProc.au3>
Global $sProductFilePath = @SystemDir
Global $sProductFileName = "CMD.exe"
Global $sProductName = FileGetVersion($sProductFilePath & "\" & $sProductFileName, "ProductName")
Global $hProcessWnd, $aProcessList, $idMsgBox
Global $iTimerInit = TimerInit()
Global $iIdleTime = _Timer_GetIdleTime()
While 1
    $aProcessList = ProcessList($sProductFileName)
    If $aProcessList[0][0] >= 2 Then
        MsgBox(48, $sProductName, "Multiple Licenses Detected" & @CRLF & @CRLF & "Due to license limitations only one copy of " & $sProductName & " is allowed." & @CRLF & @CRLF & "Please close additional copies of " & $sProductName)
        $iTimerInit = TimerInit()
        $iIdleTime = _Timer_GetIdleTime()
        ContinueLoop
    EndIf
    $iProcessId = ProcessExists($sProductFileName)
    If $iProcessId Then
        $hProcessWnd = _GetHwndFromPID($iProcessId)
        If WinActive($hProcessWnd) Then
            $iTimerInit = TimerInit()
            $iIdleTime = _Timer_GetIdleTime()
        EndIf
        ;~ If the timer is more than 40 minutes then send message to user and close the process, otherwise it closes within 5 minutes
        If TimerDiff($iTimerInit) >= 10 * 1000 Or $iIdleTime >= 10 * 1000 Then
            $idMsgBox = MsgBox(48, $sProductName, $sProductName & " has been idle for more than 40 minutes and will be closed in 5 minutes if no activity is detected.", 10)
            If $idMsgBox = -1 Then ProcessClose($sProductFileName)
        EndIf
    EndIf
    Sleep(100)
WEnd

;Function for getting HWND from PID
Func _GetHwndFromPID($_iProcessId)
    Local $_hProcessWnd
    Local $iWinList, $_aWinList = WinList()
    For $i = 1 To $_aWinList[0][0]
        If $_aWinList[$i][0] <> "" Then
            $iWinList = WinGetProcess($_aWinList[$i][1])
            If $iWinList = $_iProcessId Then
                $_hProcessWnd = $_aWinList[$i][1]
                ExitLoop
            EndIf
        EndIf
    Next
    Return $_hProcessWnd
EndFunc;==>_GetHwndFromPID

 

i was trying your script and im getting script paused problem please can you help me and i was traying to change the time to 3 min

Link to comment
Share on other sites

Don't know what script paused problem means, do you mean when you click on the system tray icon, just add #NoTrayIcon to the top of your script and add HotKeySet to create exit the script.

To change the time just modify the following lines in the code (updated for 3 minutes).

;~ If the timer is more than 3 minutes then send message to user and close the process, otherwise it closes within 5 minutes
        If TimerDiff($iTimerInit) >= 3 * (60 * 1000) Or $iIdleTime >= 3 * (60 * 1000) Then
            $idMsgBox = MsgBox(48, $sProductName, $sProductName & " has been idle for more than 40 minutes and will be closed in 5 minutes if no activity is detected.", 5 * (60 * 1000))
            If $idMsgBox = -1 Then ProcessClose($sProductFileName)
        EndIf

 

Link to comment
Share on other sites

Sorry for the double post, I wasn't aware of this one until now. The other should be closed. Maybe a mod could do it...

https://www.autoitscript.com/forum/topic/185122-close-idle-application/

Anyway here what I posted in the other thread (there was a minor bug) :

include <Timers.au3>
#include <FileConstants.au3>

Global Const $IDLE_MINUTES = 1, $TIME_WAITING = 10, $TIME_DESC = Not Mod ($TIME_WAITING, 60) ? "Minutes" : "Seconds"
Global Const $sProductFilePath = @WindowsDir
Global Const $sProductFileName = "Notepad.exe"
Global Const $sProductName = FileGetVersion($sProductFilePath & "\" & $sProductFileName, $FV_INTERNALNAME)

Global $hProcessWnd, $aProcessList, $idMsgBox
Global $iTimerInit = TimerInit()
Global $iIdleTime = _Timer_GetIdleTime()
While 1
  $aProcessList = ProcessList($sProductFileName)
  If $aProcessList[0][0] >= 2 Then
    $idMsgBox = MsgBox(48, $sProductName, "Multiple Licenses Detected" & @CRLF & @CRLF & "Due to license limitations only one copy of " & $sProductName & " is allowed." & @CRLF & @CRLF & "Please close additional copies of " & $sProductName)
    $iTimerInit = TimerInit()
    ContinueLoop
  EndIf
  $iProcessId = ProcessExists($sProductFileName)
  If $iProcessId Then
    $iIdleTime = _Timer_GetIdleTime()
    $hProcessWnd = _GetHwndFromPID($iProcessId)
    If WinActive($hProcessWnd) Then $iTimerInit = TimerInit()
    If TimerDiff($iTimerInit) >= $IDLE_MINUTES * 60 * 1000 Or $iIdleTime >= $IDLE_MINUTES * 60 * 1000 Then
      $idMsgBox = MsgBox(48, $sProductName, $sProductName & " has been idle for more than " & $IDLE_MINUTES & " minutes and will be closed in " & _
          $TIME_WAITING & " " & $TIME_DESC & " if no activity is detected.", $TIME_WAITING)
      If $idMsgBox = -1 Then
        ProcessClose($sProductFileName)
      Else
        $iTimerInit = TimerInit()
      EndIf
    EndIf
  EndIf
  Sleep(100)
WEnd

;Function for getting HWND from PID
Func _GetHwndFromPID($_iProcessId)
  Local $_hProcessWnd
  Local $iWinList, $_aWinList = WinList()
  For $i = 1 To $_aWinList[0][0]
    If $_aWinList[$i][0] <> "" Then
      $iWinList = WinGetProcess($_aWinList[$i][1])
      If $iWinList = $_iProcessId Then
        $_hProcessWnd = $_aWinList[$i][1]
        ExitLoop
      EndIf
    EndIf
  Next
  Return $_hProcessWnd
EndFunc   ;==>_GetHwndFromPID

 

Link to comment
Share on other sites

21 hours ago, Subz said:

Don't know what script paused problem means, do you mean when you click on the system tray icon, just add #NoTrayIcon to the top of your script and add HotKeySet to create exit the script.

To change the time just modify the following lines in the code (updated for 3 minutes).

;~ If the timer is more than 3 minutes then send message to user and close the process, otherwise it closes within 5 minutes
        If TimerDiff($iTimerInit) >= 3 * (60 * 1000) Or $iIdleTime >= 3 * (60 * 1000) Then
            $idMsgBox = MsgBox(48, $sProductName, $sProductName & " has been idle for more than 40 minutes and will be closed in 5 minutes if no activity is detected.", 5 * (60 * 1000))
            If $idMsgBox = -1 Then ProcessClose($sProductFileName)
        EndIf

 

Thank you very much everything work fine u are the best 

Link to comment
Share on other sites

20 hours ago, Nine said:

Sorry for the double post, I wasn't aware of this one until now. The other should be closed. Maybe a mod could do it...

https://www.autoitscript.com/forum/topic/185122-close-idle-application/

Anyway here what I posted in the other thread (there was a minor bug) :

include <Timers.au3>
#include <FileConstants.au3>

Global Const $IDLE_MINUTES = 1, $TIME_WAITING = 10, $TIME_DESC = Not Mod ($TIME_WAITING, 60) ? "Minutes" : "Seconds"
Global Const $sProductFilePath = @WindowsDir
Global Const $sProductFileName = "Notepad.exe"
Global Const $sProductName = FileGetVersion($sProductFilePath & "\" & $sProductFileName, $FV_INTERNALNAME)

Global $hProcessWnd, $aProcessList, $idMsgBox
Global $iTimerInit = TimerInit()
Global $iIdleTime = _Timer_GetIdleTime()
While 1
  $aProcessList = ProcessList($sProductFileName)
  If $aProcessList[0][0] >= 2 Then
    $idMsgBox = MsgBox(48, $sProductName, "Multiple Licenses Detected" & @CRLF & @CRLF & "Due to license limitations only one copy of " & $sProductName & " is allowed." & @CRLF & @CRLF & "Please close additional copies of " & $sProductName)
    $iTimerInit = TimerInit()
    ContinueLoop
  EndIf
  $iProcessId = ProcessExists($sProductFileName)
  If $iProcessId Then
    $iIdleTime = _Timer_GetIdleTime()
    $hProcessWnd = _GetHwndFromPID($iProcessId)
    If WinActive($hProcessWnd) Then $iTimerInit = TimerInit()
    If TimerDiff($iTimerInit) >= $IDLE_MINUTES * 60 * 1000 Or $iIdleTime >= $IDLE_MINUTES * 60 * 1000 Then
      $idMsgBox = MsgBox(48, $sProductName, $sProductName & " has been idle for more than " & $IDLE_MINUTES & " minutes and will be closed in " & _
          $TIME_WAITING & " " & $TIME_DESC & " if no activity is detected.", $TIME_WAITING)
      If $idMsgBox = -1 Then
        ProcessClose($sProductFileName)
      Else
        $iTimerInit = TimerInit()
      EndIf
    EndIf
  EndIf
  Sleep(100)
WEnd

;Function for getting HWND from PID
Func _GetHwndFromPID($_iProcessId)
  Local $_hProcessWnd
  Local $iWinList, $_aWinList = WinList()
  For $i = 1 To $_aWinList[0][0]
    If $_aWinList[$i][0] <> "" Then
      $iWinList = WinGetProcess($_aWinList[$i][1])
      If $iWinList = $_iProcessId Then
        $_hProcessWnd = $_aWinList[$i][1]
        ExitLoop
      EndIf
    EndIf
  Next
  Return $_hProcessWnd
EndFunc   ;==>_GetHwndFromPID

 

 thank you for your response i was trying everything , now it worked 

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...