AutoHotKey: catching & manipulating windows without human interaction - automation

Something sounding very basic has taken a lot of time: how can an AutoHotKey script be programmed to wait for a specific window and then accept it, Send {enter}, to close it down? In this case it’s an annoying settings confirmation dialogue which comes up every time certain file types are opened for a programme. A minor complication is also that the windows title changes every time, while its ahn_class is shared with the mother programme – things which i’ve tried to tackle by catching the window by its pixel size instead:
#IfWinActive ahk_class SALFRAME
~LButton::
WinGetActiveStats, , width, , ,
if (width = "681") {
Send {enter}
}
return
This works, but forces to click somewhere on the dialogue when it comes up, which is faster then before, but still not really automated. I also tried with WinWaitActive among other things, but it doesn’t seem to catch the window (at some point some of the scripts i’ve tried to write actually killed the window when the script was executed, but only once, without touching subsequent windows coming after the script first ran). What is the correct way to wait for and terminate certain windows without human input with AutoHotKey?

#Persistent
SetTimer, Send_Enter_to_specific_window, 50
return
Send_Enter_to_specific_window:
IfWinActive ahk_class SALFRAME
{
WinGetPos,,, width,, A
if (width = "681")
Send {enter}
}
return
https://autohotkey.com/docs/commands/SetTimer.htm#Examples

Related

Send vs SendInput Problems

I've tried many variations of a script whose purpose is to send rapid clicks when either mouse button is held down. In my own script I have both left and right click loops but here is the simplest version I tried:
SetKeyDelay, -1
$RButton::
While GetKeyState("RButton", "P") {
Send, {RButton}
}
Returm
When using this, I get about 20 clicks per second. However, I would like to achieve 30 or so. What I infer from this, is that the send command has a 50 ms delay (1000ms/20 clicks). I would also like to use the {Blind} modifier but that slows it down even more (to about 16 clicks per second).
The obvious answer I think is to use SendInput, and I was able to achieve desired clicks per second using SendInput. However, it came with undesirable side effects. Namely, the key buffering is very unwanted in my use case. In addition, no matter if I used a while loop with GetKeyState or a Button up configuration with SetTimer and Gosub, the right click and left click loops would get stuck occasionally (interference?). The loops getting stuck was not a problem with Send as I'm able to put the loops for each mouse button in separate scripts. When I do that with SendInput, it lowers the clicks per second drastically.
I have also tried SendPlay and SendEvent to no success. Also, I tried using V2 although most of my testing has been in 1.1.35.00.
I don't think it is CPU or memory related as SendInput is able to hit the clicks per second goal of 30 and both CPU and memory stay at about 60%. I could be wrong here though. I also don't think the application I am using is restricting the click rate for the same reason of it being able to register 30 with SendInput.
I greatly appreciate anyone who takes the time to read this! Happy Holidays!
Expecting about 30 clicks per second with both right and left mouse buttons being held down.
I've tried:
Send, SendInput, SendPlay, SendEvent
#MaxThreadsPerHotkey, 2 #SingleInstance Force
SetKeyDelay, -1 SetBatchLines, -1
While loop with GetKeyState as condition and also tried SetTimer and Gosub with individual functions
V2 and 1.1.35.00.
Resulted always in a maximum of 16 clicks per second with Send
With SendInput, user keystrokes sent while clicking were always buffered, which was undesired. As well as the loops getting stuck occassionally

vim: discard pending keyboard input

Background:
I'm writing a fuzzy-finding vim plugin which runs a graphical program as a separate process. It opens a window, you type into it, press return, and then the vim plugin processes its output and navigates to the file / buffer you selected.
The time between triggering the find function and the new process grabbing keyboard input is a fraction of a second, so it's possible to accidentally type too soon, which causes that input to be delivered to vim.
Given that vim is single-threaded, I know (and have verified) that the errant keyboard input is not actually processed until the program finishes - the input is buffered while the program runs, and afterwards the random keys I typed are interpreted as vim actions.
Question:
How can I discard input that's sitting in vim's input buffer but has not yet been processed?
inputsave() takes pending keyboard input and saves it onto a stack. This would be what I want, except that it causes a memory leak if I don't match it with a call to inputrestore(). Is it possible to discard the stored input without executing it?
If that's not directly possible, can anyone think of a good way to discharge those events into a safe place? i.e call inputrestore() in such a state that the stored input will have no visible effect.
I need to do this in both a normal-mode mapping, and a command-mode mapping. So I'd prefer a solution which doesn't abandon the current command-mode input.

Kill application not Process - VB

I have a program that out of my control will bring up a message box (I didn't write or have source code)
I am trying to find out if it is possible to write a program (visual studio) that can at a set time, say every 10 minutes close all open applications(msgbox) but keep the process going? The application/task name is different to the process name.
It runs on XP and 7.
I've tried google but haven't managed to find what I'm after, all i can find is process kill. Not 100% sure on correct terminology.
You might be better-off writing a program that finds a current open dialog (window, messagebox, etc) and closing it. Sending an Esc keystroke is a pretty easy approach. Here is another SO article that talks about doing this: How to send a mouse click event to a hidden window?

VB.Net automate flash in WebBrowser

I've passed many hours searching the web for a solution to something which seems obvious, but without results.
I need to automate a task in a Flash application running on my intranet.
I can't change the Flash application nor do I have access to the source code.
it's not a Flash movie but an application.
I can't download the swf.
I'm using a WebBrowser in a form. The Flash app is displaying without issues.
So far, I have been able to automate the task (clicking on some buttons, then inputting text and finally saving the results on a server). It works but it's not clean at all because I use hard-coded timers to wait a given action is done and then I click on very specific point at given coordinates in the application.
What I would like to do:
Avoid hard-coded timers. the Flash application takes some time to display all elements on the window (from 20 to 60+ sec). I would like to be able to detect when all elements are loaded. I tried to retrieve the text of the windows handle, but while I can retrieve the Flash hwnd, I can't retrieve the content (through messages).
In brief, instead of waiting 60sec (and not being 100% sure it's enough), if the last element to load in the Flash app has "ABC" written in it, I would like to detect it's displayed so that I can continue the sequence (click on the next button).
I'm using VB.net. Any hints to achieve that would be appreciated.
Lol. I am trying to do the same thing but with no results. You can try to see if there are POST/GET codes that can help you if the application has an online nature. Other than that you can only simulate clicks, because flash can't be easily interacted with. This is why most of the things are going to swap with HTML5 now.

How can Sikuli be used to wait for a button for a long time, with perhaps some maintenance task in between?

I have a webpage where I am waiting for a button to appear, and when it appears I would like to click it. The button is on a timer and may take as long as an hour to appear. Also, if the button takes longer than a certain length of time to appear, I'd like to move the mouse (otherwise the website will log me out automatically).
So, to wait for a button to appear I devised this Sikuli script:
button = "button.png"
while(1):
if exists(button):
print("found it")
click(button)
break
else:
print("wait longer")
wait(button,30*60)
# do a regular task
print "all done!"
The above does not seem to be functional. If the button is on screen, the script will find it... However, if it has to wait it will simply time out quickly with a FindFailed exception (on the click() even though the button does not exist on screen). I considered writing a handler, but seems like overkill.
What am I doing wrong and what is the best way to wait a long period for a visual event like this?
Some other thoughts for you...
while(1):
wait(Button, 30*60) # This will spinlock for 30 minutes for the button to appear
if exists(Button):
hover(Button) # Debug statement allowing user to see what Sikuli has matched to
click (Button)
else:
mouseMove(Location(50,100))
mouseMove(Location(50,200))
Links:
wait
mouse movement link
Location
Maybe Sikuli recognizes something that looks quite your button, and tries to click it.
If you right click in the IDE your button pattern, you can fine tune the tolerance level for recognition. Try to cut the image exactly around your button and increase the value to be more precise.
I suggest you to read this tutorial
http://doc.sikuli.org/tutorials/surveillance/surveillance.html
and to set up a event handler to manage your button when it appears
http://doc.sikuli.org/region.html#Region.onAppear
http://doc.sikuli.org/region.html#observingvisualeventsinaregion
It is not much code to write.
You can get a nice example with full source code in Sikuli's Blog here
http://sikuli.org/blog/2011/08/15/sikuli-plays-angry-birds-on-google-games/
I think you can just set up your handlers and go with
observe(FOREVER)
If you want sikuli to do stuff while your waiting for an image i would use the onAppear(pic, function) and observe(FOREVER, true) methods this is how it works
event = Sikuli.event
def function(event):
click(yourButton.png)
onAppear(picYourWaitingFor.png, function)
observe(FOREVER, true)
basically what this does is onAppear will continuously scan the screen for picYourWaitingFor.png. sikuli continues execution after words so it's scanning while its working. on the appearance of said pic it will jump to the function you put down as the second parameter of onAppear.
I have this same issue as described. Its not about waiting forever. And Observe won't work either, because that does watch forever. Think about wanting to check for event only for a certain period of time say 60 seconds. If it doesn't occur, move on. This could be happening in a specific series of events. If the image doesn't appear in the 60 seconds, move on to do another series.
wait(image,60)
...will crash after 60 seconds if it doesn't find the image, which isn't what is wanted at all in my case.
So I did something like this:
attempt = 1
count=0
while attempt:
if exists(image):
attempt=0
else:
count=count+1
if count>60:
attempt=0
else:
wait(1)
Probably a better way and doesn't give an exact time, but approach doesn't crash the script.
You could also try: except it.. Should be shorter.