autohotkey: how to set up a watchdog - autohotkey

My AHK script's expected run time is somewhere between 5 minutes and 25 minutes depending on the events. And it is mostly doing screen scraping off of a browser, searching for patterns and taking actions (by clicking certain zones on the screen) accordingly. And terminating the browser session when all is done. And I scheduled it to run every hour from windows task scheduler.
My problem is, when there is a network problem or my workstation CPU is having a senior moment, the time allow for the web page to load gets to be insufficient (usually around 15 seconds and it is not feasible to make it longer as contents may change in 30 seconds) Or in the middle of the process something may get hung.
If such a thing happens, I want the AHK script to exit and just before exiting, I want it to terminate all browser sessions (chrome in this particular case)
So far, I am unable to come up with a "single script" solution.
My current state is to start a script which monitors the contents of a file every 30 minutes, and if the contents haven't changed from the last time, open up a new google chrome session and send Shift-Ctrl-Q key sequence to close all instances of chrome. Meanwhile, my main script, updates the same file upon completion with a number different than the previous value in it and it is unique. Deficiency of this approach: I don't know how to kill the other AHK script (hung one) without killing this watchdog script.
And my ultimate desire is to build this functionality, into the main script, which is susceptible to getting hung.
My main script
send #r
send chrome.exe http://myURL{enter}
mousemove 200,200
send ^a
send ^c
;
; using a series of IfInString commands
; determine the condition
; then use mousemove, x, y and mouseclick, l
; commands, do my deed
filedelete, c:\mydir\myfile
fileappend, newnumber, c:\mydir\myfile
exitapp
My watchdog script
loop ; forever
{
; old content is stored in variable PREV
fileread, newval, c:\mydir\myfile
if (newval = PREV)
{
send #r
send chrome.exe
sleep 10000 ; wait for chrome window to pop up
send ^+Q
; I need a way to stop my hung AHK script here but don't know how
}
else
{
PREV = %newval%
sleep 1800000 ; sleep 30 minutes
}
} ; end of loop
f10::exitapp ; when I need to stop watchdog
of course these are not the actual scripts. Just to give you an idea. Otherwise, there are lots of waiting around for pages to load etc. But gist of it is there.
Thank you for your help in advance

I have provided some AutoHotkey code blocks that should resolve the issues you describe.
I would try and write both scripts, so that if both scripts were terminated,
it would be possible to do some checks and resume as if nothing
had happened, i.e. add in more flexibility.
I personally almost never use SetTimer, I just use loops with Sleep,
I don't think it would help improve the script in this case.
I have found that for scripts that have hung, but for where there is no error message to state that they have terminated,
you can retrieve the hWnd (window handle) and PID (process ID) and thus terminate them.
Some of the tasks you describe may be achieved more easily by using UrlDownloadToFile
or WinHttpRequest (see examples on the forum) to download webpages, and then by parsing the html.
Other tasks may be more easily accomplished by using Internet Explorer with COM (Component Object Model),
to query/manipulate web elements in a live webpage.
-
;to launch Chrome and wait for it to open (with an optional delay afterwards)
;if the window is not seen within 60 seconds, ErrorLevel is set to 1 and action can be taken
Run, "C:\Program Files (x86)\Google\Chrome\Application\chrome.exe" "https://www.google.com/"
WinWaitActive, ahk_class Chrome_WidgetWin_1, , 60
if ErrorLevel
{
MsgBox error ;put code here
}
else
{
Sleep 10000
;put code here
}
;to launch Internet Explorer and wait for it to open (with an optional delay afterwards)
Run, "C:\Program Files\Internet Explorer\iexplore.exe" "https://www.google.com/"
WinWaitActive, ahk_class IEFrame
Sleep 10000
;to terminate a script
DetectHiddenWindows, On
vPathScript = %A_ScriptDir%\my script.ahk
WinGet, hWnd, ID, %vPathScript% - AutoHotkey v ahk_class AutoHotkey
IfWinExist, ahk_id %hWnd%
{
WinGet, vPID, PID, ahk_id %hWnd%
Process, Close, %vPID%
}

Process Watchdog using:
- 2 local PC's with shared folders
- 3 ahk Scripts
PC-1 ahk Process script (loops forever)
auto start at windows startup
LOOP
put a WD file on PC-2
run some process
wait some time
go to LOOP
PC-1 ahk WD-1 script
auto start at windows startup (loops forever)
if initial startup set Counter and put WD file in local shared folder
LOOP
wait some time
if local WD file doesn't exist decrement Counter
if Counter = Zero Send Email
if local WD file exists reset Counter and delete local WD file
go to LOOP
PC-2 ahk WD-2 script
auto start at windows startup (loops forever)
if initial startup set Counter and put WD file in local shared folder
LOOP
wait some time
if local WD file doesn't exist decrement Counter
if Counter = Zero Send Email
if local WD file exists reset Counter and delete local WD File
put WD file on PC-1
go to loop
Basic Failure Scenarios:
Process script Fails ... PC-1 and PC-2 WD scripts will send emails
PC-1 Fails ... PC-2 WD script will send email
PC-2 Fails ... PC-1 WD script will send email

Related

How do I update the auto hot keys config once saved from a script?

I have a shortcut to open the current running script in a text editor and then save it and close it. Upon closing, how do I update ahk to use the new updated settings?
This is what I have:
IfWinExist, test.ahk ahk_exe notepad.exe
{
WinActivate
Sleep, 100
Send, ^s
Sleep, 200
WinClose
}
else
MsgBox, window not found
app1Open=false
Reload
If you want to restart the script itself (that is, from its own process), use the Reload command.
Otherwise, if you want to restart the script from another process, you have to close it and then run the script again. In this case, you can either kill the script's process and run it again (not nice!). Or you can tell the script to gracefully Reload, for example in one of these two ways:
Inter-process communication: OnMessage() for the receiving process and PostMessage/SendMessage in the sending process
Defining a simple hotkey in your receiving script and sending that hotkey from another process
As MCL mentioned, use Reload. There is no need to close the script. Here is an example:
^!#r:: ; Save and Reload the script with Alt+Ctrl+Win+r
IfWinExist, SciTE4AutoHotKey
{
WinActivate
Sleep, 100
Send, ^s
Sleep, 300
}
Reload
Return

AutoHotkey to use clipboard info to open files in Word works in Win8 but not in Win7

I created an AHK macro for a colleague. I have Windows 8; she has Windows 7. She has two "pending work" folders, one for documents and the other for audio files. The (text) file names in the documents folder correspond to the file names in the audio folder. So, for example, if there is an audio file called abc123.mp3 in the audio folder, there will be a file named abc123.txt in the documents folder.
As she opens the audio file in her transcription (media player) app, as part of that process, I want to have an AHK macro automatically open the matching text file (in Word).
I created an AHK macro that picks up from the point of her selecting the file to open from her transcription app. At the point where she selects the file, she invokes the AHK shortcut, which then toggles the rename feature (F2), copies the text to the clipboard (Ctrl+C), opens the file (Alt+O), and then uses the clipboard info (along with path info) to open the appropriate text file in Word.
It's working PERFECTLY on my system. However, when I logged into her system earlier today to demo the macros, the macro would not work. It works to a point - it will rename the file, copy the name of the file, and open the audio file, and file name is in the clipboard. But that's where it dies, with no error message. During troubleshooting, I tried isolating the macro down to one command - to simply open (fixed name) file in WinWord.exe, but that doesn't work, either.
I have been unable to find any research related to this issue. I know there are numerous ways to accomplish this task, but my AHK scripting skills and my free time are limited, so I went with what I knew I could accomplish quickly. I am open to suggestions for how to troubleshoot or tweak this macro to get it working on her system. It's hard to troubleshoot when it works on mine!
NumpadEnter::
Send {F2}{Sleep 100}
Clipboard=
Send ^c
Send {Sleep 100}!o{Sleep 100}
Run, WinWord.exe "C:\DocFiles\"%Clipboard%.txt
Return
Just a guess, but I believe you wanted Sleep command and not a Sleep Key? Be sure that you are using the Latest Version of AutoHotkey you can download it from www.ahkscript.org
NumpadEnter::
Send {F2}
Sleep, 100
Clipboard=
Send, ^c
Run, WinWord.exe "C:\DocFiles\"%Clipboard%.txt
Sleep 100
Send, ^o
Sleep 100
Send, ^v
Sleep 100
Send, !o
Return
Edit:
In the script you posted, you are telling the computer to Send a Sleep Key by placing brackets around the word Sleep. Like so {Sleep}
Furthermore, you are also telling your script to not just Send one key... you are telling it to Send the Sleep Key 100 times by placing the number 100 in the brackets, separated by a space, with the named key. Like so: {Sleep 100}
I fail to see how you would want to have your script simulate 100 Sleep key presses?
What I posted above uses the Sleep Command which delays the script in milliseconds. I believe this is truly what you want.

IfWinExist not happening

To check that my local servers are online as seen from the WAN, I have a PHP script on a remote web site that tests my servers every 5 minutes, and a report is returned to my local browser. If something is wrong, some javascript also changes the title. My AHK script should then recognise the title change within 10 seconds, and bring the browser window to the top.
#NoEnv ; Recommended for performance and compatibility with future AutoHotkey releases.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
;
^F1::Send Dave Kimble
...
;
SetTitleMatchMode 2
Loop {
IfWinExist, Server Error
{ WinActivate
return
}
Sleep 10000
return
}
The PHP script works OK, however the AHK script doesn't seem to recognise the title change. Indeed it doesn't seem to clock any CPU time at all after the initial load.
What am I doing wrong?
As soon as your loop reaches the second return, the loop will exit.
You will also have to move ^F1::Send Dave Kimble after your loop since it prevents the script from reaching the loop statement.

Hotkey to restart autohotkey script?

Say I have an autohotkey script C:\path\to\my\script running. Is there a way to define a hotkey that re-starts it?
In order to prevent duplicate instances, I normally do not re-launch a script but use the build-in function Reload. I launch this with Ctrl+Win+Alt+R and use Ctrl+Win+Alt+E to edit the main AHK script.
^#!r::Reload
Actually, my script looks like this:
^#!r::
Send, ^s ; To save a changed script
Sleep, 300 ; give it time to save the script
Reload
Return
^!#e::Edit
As a matter of fact, all the way at the top of my script I have this to give me a visual and audio indication that the script was restarted:
#SingleInstance Force
#installKeybdHook
#Persistent
Menu, Tray, Icon , Shell32.dll, 25, 1
TrayTip, AutoHotKey, Started, 1
SoundBeep, 300, 150
Return
Make a hotkey that runs a script, which in this case is the same script and then exit.
somehotkey::
Run, C:\path\to\my\script.ahk
ExitApp
return
I found this to be the safest option of them all, because it takes care that the correct script is reloaded when you have multiple scripts running simultaneously, which was a recurring issue for me. The combination of the following also ensures that only one instance of a script will ever run at a time. The ScriptFullPath variable includes the name of the script.
#SingleInstance Force ;put this at the top of the script
^r::run, %A_ScriptFullPath%

How to simulate key press on a background window

I need to force Outlook which is in the background, to check for new emails every 2 seconds. So I wrote a following script but it doesn't do it. What's wrong? I don't want the script to disturb what I do and give the focus to the Outlook window. The "ahk_class rctrl_renwnd32" is correct, I checked it with "WinActivate, ahk_class rctrl_renwnd32" and it worked.
Loop
{
ControlSend,, {F9}, ahk_class rctrl_renwnd32
Sleep 2000 ; Wait 2 seconds
}
There is no error in your code. The problem might be in the receiving application. When I test this in Notepad, an F5 (Print time & date) is executed when the Notepad window is open somewhere on my second screen. As soon as I minimize Notepad, it will no longer execute F5, but it still accepts a string like A{Enter}B{Enter}C{Enter} when minimized.
!q::
ControlSend,, {F5}A{Enter}B{Enter}C{Enter}, ahk_class Notepad
Return
Solution, Try if this works when you keep the window on screen somewhere (no need to have the focus).
I have used Outlook in the past and remember that F9 took some time to execute. Running this every 2 seconds looks like overkill.
If getting your e-mail in time is THAT important that you are willing to "kill" the mail server with refresh requests, I would discuss a solution with your IT support.