Jarbydev Posted April 25, 2018 Share Posted April 25, 2018 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 More sharing options...
Subz Posted April 26, 2018 Share Posted April 26, 2018 You can try something like the following: expandcollapse popup#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 Jarbydev 1 Link to comment Share on other sites More sharing options...
Jarbydev Posted April 26, 2018 Author Share Posted April 26, 2018 The Script works Perfectly, but the idmsgbox, is disappering in less of 2 seconds, Link to comment Share on other sites More sharing options...
Subz Posted April 26, 2018 Share Posted April 26, 2018 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 More sharing options...
Jarbydev Posted April 26, 2018 Author Share Posted April 26, 2018 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 More sharing options...
Subz Posted April 26, 2018 Share Posted April 26, 2018 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. expandcollapse popup#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 More sharing options...
savu Posted May 16, 2018 Share Posted May 16, 2018 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 More sharing options...
Earthshine Posted May 16, 2018 Share Posted May 16, 2018 (edited) 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 May 16, 2018 by Earthshine My resources are limited. You must ask the right questions Link to comment Share on other sites More sharing options...
Earthshine Posted May 16, 2018 Share Posted May 16, 2018 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 More sharing options...
savu Posted May 16, 2018 Share Posted May 16, 2018 Thank you Eartshine. Yes it's a server with several users connected. regards, Silviu Link to comment Share on other sites More sharing options...
nikolay_bu Posted January 18, 2020 Share Posted January 18, 2020 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. expandcollapse popup#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 More sharing options...
Subz Posted January 18, 2020 Share Posted January 18, 2020 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 More sharing options...
Nine Posted January 18, 2020 Share Posted January 18, 2020 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) : expandcollapse popupinclude <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 “They did not know it was impossible, so they did it” ― Mark Twain Spoiler Block all input without UAC Save/Retrieve Images to/from Text Monitor Management (VCP commands) Tool to search in text (au3) files Date Range Picker Virtual Desktop Manager Sudoku Game 2020 Overlapped Named Pipe IPC HotString 2.0 - Hot keys with string x64 Bitwise Operations Multi-keyboards HotKeySet Recursive Array Display Fast and simple WCD IPC Multiple Folders Selector Printer Manager GIF Animation (cached) Screen Scraping Multi-Threading Made Easy Link to comment Share on other sites More sharing options...
nikolay_bu Posted January 19, 2020 Share Posted January 19, 2020 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 More sharing options...
nikolay_bu Posted January 19, 2020 Share Posted January 19, 2020 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) : expandcollapse popupinclude <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 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