IfWinExist not happening - autohotkey

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.

Related

Fix Labview Alt-Tab behaviour with Autohotkey

Did anyone try to fix the way Labview interferes with normal Alt-Tab behaviour using Autohotkey?
Alt-Tab inside Labview puts all non-labview windows to the end of the list.
So if you have just alt-tabbed to labview window from your browser it takes
(2 × number_of_currently_open_labview_projects -1)
keystrokes to get back.
Great idea. I find that functionality annoying and there doesn't appear to be an easy fix anywhere on the web. Here's my script. Two quick notes:
I had a lot of trouble re-mapping Alt-Tab. If that's critical you can try starting here for help.
To my knowledge it's not possible to get rid of the "screen flicker" because Windows requires some delay between keystrokes.
Note: to adapt this code for various Windows - look up the "ahk_class" using the Window Spy tool included in the AutoHotkey installer .
Code
#NoEnv ; Recommended for performance and compatibility with future
AutoHotkey releases.
#Warn ; Enable warnings to assist with detecting common errors.
SendMode Input ; Recommended for new scripts due to its superior speed and reliability.
SetWorkingDir %A_ScriptDir% ; Ensures a consistent starting directory.
#NoTrayIcon
#SingleInstance force
SetTitleMatchMode 2 ;partial search mode
#IfWinActive vi
#q:: ;there were issues mapping to Alt+Tab
CountOfVIs := -1
WinGet, id, list,ahk_class LVDChild,, Program Manager
Loop, %id%
{
CountOfVIs := CountOfVIs +1
}
msgbox, # of VIs open: %CountOfVIs% ;when I remove this it doesn't work - must be an AHK thing
Send {Alt down}
Loop,%CountOfVIs%
{
Send {tab}
Sleep,50 ;if this is too low it doesn't work
}
Send {Alt up}
I've recently found an article related to this problem, but unfortunately it is in Russian.
It references the following blog with a python script (+autohotkey mapping) that seems to be solving the problem without the "screen flicker".

autohotkey: how to set up a watchdog

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

Send, SendInput, SendEvent functions entering single key multiple times

I have created a script in AutoHotKey.I have to Enter the entire file path to be opened in the
file browser.i have used send function but it passes the same keys multiple times. I tried using the function SetKeyDelay but still it enters the keys multiple times. I tried other alternatives as sendInput and SendEvent but still it didnt work.
Even if i terminate the script in between and if the control switches to some Input box or Editor, it starts entering the values into that area. Send function keeps on entering the keys even after the script execution is terminated.
Script:
;Open Adobe Acrobat 8.
run Acrobat.exe sleep, 1000
WinWait, Adobe Acrobat Professional,
Sleep, 1000
;Open Compare Documents Window
send, {ALT}A
Sleep, 1000
send, U
WinWait, Compare Documents,
;Enter File Path
IfWinNotActive, Compare Documents,
WinActivate, Compare Documents,
WinWaitActive, Compare Documents,
Sleep, 1000
send, !H
WinWaitActive, Open,,1000
sleep, 1000
SendEvent, "D:\Sample\a.pdf"
It Enters text something like this
CCCC:::::\\DDDDiiiiii
Things to try:
Update AutoHotkey to the latest version.
Don't use SendEvent. It allows other input to interrupt the text as it is being entered. Use SendInput instead. It is recommended to put the following at the top of all your scripts:
#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.
SendMode Input changes Send to use SendInput instead of SendEvent. It buffers the input and sends it all at once instead of letting other keyboard/scripts interrupt the text. See: Send for more information.
Restart your computer and make sure that there are no other AutoHotkey programs running, or that there isn't multiple instances of your Autohotkey script running. This is especially a problem when testing, as you might have launched the same script multiple times, and if the thread hasn't been properly terminated, you may have multiple instances there waiting for the Open window to be activated. Once the Open window has been activated, then you may have 4+ dormant scripts all trying to type at the same time, which would give you the output that you are describing.

autohotkey inside autohotkey

Is there a way to write an autohotkey within an autohotkey? For instance, I have an autohotkey that opens some websites in tabs at work for me & I have an autohotkey that when typed puts in my username & password for some of those sites. Is there a way to put the password autohotkey (actd(at symbol)) inside the IE tabs autohotkey? I did some searching, & it doesn't look like {#} can be sent, so I wasn't sure if there was another way to do it.
Your AutoHotKey script can #Include other scripts, assuming they are not #Persistent. You could loop through your list of tabs, and then call one or more other scripts.
As far as sending the # sign, you should be able to use the Send command without problems. If you do encounter a strange problem, then you can try using the SendRaw command or use the syntax: Send {raw}#
If this doesn't answer your question, please paste some code of what you are trying to get working.
What you can do is write two separate scripts. One does not have an autohotkey assigned, but gets called by the initial script. In your case, you have said that you already have a tabopening hotkey, so I will use a VERY rudimentary example of both scripts, but demonstrate how to send the # symbol and call another script from within a hotkey.
The two scripts I would use are:
tabOpener.ahk, and
passwordEntry.ahk
And they would appear as follows:
tabOpener.ahk
#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.
; hotkey is set as WinowsKey+t and checks if FireFox exists, if so, it makes it active, if not, it starts FireFox
~#t::
IfWinExist, ahk_class MozillaWindowClass
{ WinActivate
Send ^t
} else run firefox
;Upon opening a new tab in FireFox, the address bar has already got focus,
;so send the web address (You can use COM functions for this, and are highly
;recommended, but out of the scope of this example)
Send, hotmail.com{Enter}
;Waits until page is loaded. Again COM functions are available as they can tell
;when a page is finished loading, but that is a more involved example.
Sleep 5000
;Calls the password entry script.
Run passwordEntry.ahk
return
passwordEntry.ahk
#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.
;When using send, adding the {Raw} tag will literally interpret every
;character in the remainder of a string. For instance ^ will send ^
;instead of a Control keypress.
Send {Raw}Username#domain.tld
Send {Tab} {Raw}Password
Hopefully that helps. This example showed the use of the {Raw} tag for sending special characters (http://www.autohotkey.com/docs/commands/Send.htm), in addition to calling a separate script from within one's existing hotkey using Run / Runwait (http://www.autohotkey.com/docs/commands/Run.htm).
;~ Alt+1 to send username (email format) and password
!1::Send, myUsername#mydomain.com{tab}myPassword{enter}
depending on you web browser you could use COM objects to handle this very easily. You would find the user id password fields and then for example:
url := "http://yourwebsite.com"
wb := ComObjCreate("InternetExplorer.Application") ; create broswer object
wb.navigate(url)
wb.visible := true ; sets the browser as visible, defaults as not
While (wb.busy || wb.readyState <> 4)
Sleep 100<br>
wb.document.all.username.value := "yourname#wherever.com"
wb.document.all.password.value := "Pa$$word15"
wb.document.all.btnLogin.click()
this however depends on if you are using IE to access your site or not. Look at COM objects in the docs a bit to get a feel for it, and you will learn some really basic things about the DOM, here: Basic DOM MSDN. where I set the "username" & "password" and "btnLogin" control ids in our javascript, would need to be discovered by looking at your page. you should also check out out this tutorial: AHK Basic COM/JavaScript Tutorial

How can I make AutoHotkeys's functions stop working as soon as the .exe is closed?

I'm testing AutoHotkeys as a way to block user's usage of Ctrl, Alt and Windows Key while an application is running. To do this, I compiled the code:
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
into an .exe using the compiler that comes with AutoHotkeys.
My problem is that normally when I close the .exe file (either by code using TerminateProcess(,) or manually) the keys are not released immediately. The Windows Key, for example, may take something like 10 seconds to be finely "unlocked" and become able to be used again, and for me this is unacceptable.
So I got two questions:
Is there a way to fix this problem? How can I make the keys to be released as soon as the .exe is closed?
Would there be any improvement if I tryed to get the same functionality by code? Or if I create the hooks by myself I would get the same problem I'm having with AutoHotkeys?
Thanks,
Momergil
AutoHotkey has a built-in command ExitApp for terminating your scripts.
This example makes Esc your termination hotkey:
Esc::ExitApp
It seems like the delay you are experiencing might be related to how long it's taking the process to close.
You could try making the hotkeys conditional with the #If command*
(i.e. they are only blocked when Flag = 1).
Then you can have the script quickly change the context just before ExitApp by using OnExit. The OnExit subroutine is called when the script exits by any means (except when it is killed by something like "End Task"). You can call a subroutine with a hotkey by using the GoSub command.
Flag := 1
OnExit, myExit
Esc::GoSub, myExit
#If Flag
LAlt::return
LCtrl::return
x::return
#If
myExit:
Flag := 0
Exitapp
* The #If command requires Autohotkey_L.
The other option that will be more verbose, but work for AHK basic, is the hotkey command.
Another option is to have AutoHotkey run the target application, and upon application exit, AutoHotkey exits as well. Here's an example with Notepad. When the user closes Notepad, the script gracefully exits.
RunWait, Notepad.exe
ExitApp ; Run after Notepad.exe closes
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
I would use winactive to disable these keys. In this example the modyfier keys are disabled for "Evernote". As soon as you switch to another program the keys are restored and when you switch back to Evernote the modifier keys are disabled again.
SetTitleMatchMode, 2 ; Find the string Evernote anywhere in the windows title
#ifWinActive Evernote
LAlt::return
RAlt::return
LControl::return
RControl::return
RWin::Return
LWin::Return
#ifWinActive