Automating Everything in Windows
The biggest peeve that I've encountered in my career has been to witness intelligent, capable individuals perform tedious and time-consuming tasks which can be automated with tools and a little knowledge. These can be simple things like organizing files on a computer, converting data from an online database into a local one, scanning documents with a printer, or more complex things like taking a series of strength reads from an RFID reader where the physical element and software don't normally interact. I would argue that given any task which involves performing a repetitive action, one is duty bound to investigate if relevant tools exist to automate that task. I want to share examples of the one tool which I most frequently fall back on for quick automation within a Windows environment - a scripting language called Autohotkey.
For those in the know, scripting automation is not a new concept. Integrated tools such as Excel Macros, Mail Merge in Word, Powershell and other languages are great ways to do tedious tasks within well-defined software environments. Hardware tinkerers have been playing with Raspberry Pi and Arduino microcontrollers to do all sorts of script-based things such as programmable dispensing, remotely actuating a relay or monitoring a sensor to perform some action. The code and the complexity of these tools are low enough that they can be learned in a matter of hours, and perfected in a matter of days. Autohotkey is more than these tools, it is a language designed to take any possible task within a Windows environment and make it easier.
To someone looking at the Autohotkey language for the first time, they would spend 5 minutes and conclude, "It is designed to generate real-time typing shortcuts". This is because the most basic use of the language is to perform abbreviated expansions. For instance, if I type the following line in a text file, save it as .ahk and run it (yes this is all the code in the whole file)
ahk::AutoHotKey
whenever I hit the physical keys on the keyboard 'a' 'h' and 'k' without using shift, it will replace that with the word 'AutoHotKey'. Non-withstanding this is a useful feature as it enables you to generate your own 'personalized script' for things like standard email responses, automatic typesetting for wiki posts et cetera. However, the language is so much more! To keep it simple, whatever YOU as a user can do in a Windows environment, you can easily program in Autohotkey to repeat and improve.
The best part is that relatively complex tasks are converted into readable and reproducible code, the language can be run and compiled from a portable USB and it has a built in .ahk to EXE compiler for systems where you want click-to-run. I highly recommend getting the download at https://www.autohotkey.com/ and checking out the SciTE4AutoHotkey IDE to make discovering its power even easier.
Some things I've done with Autohotkey (with examples)
- Migration of a Sharepoint Wiki into Atlassian Jira (code snippet is for the simplest changes, the entire code would convert all typesetting and automatically swap from the current webpage to the Jira page and paste the content - all in Autohotkey!) Note: See also RegExReplace
;;############################################
;;# Fixes Link Notation ([[ -> [ , ]] -> ]) #
;;# Fixes Newline Notation (`r`n -> `r) #
;;############################################
^!c:: ; Press Ctrl + Alt + "c"
Clipboard =
Send, ^c
ClipWait
StringReplace, NewStr, Clipboard, [[, [, All
StringReplace, NewStr2, NewStr, ]], ], All
StringReplace, result, NewStr2, `r`n, `r, UseErrorLevel
if ErrorLevel > 0
{
StringTrimRight, result, result, 1
StringReplace, result, result, `r`r, `r, A
}
;Msgbox %result%
return
- Automate an Arduino and an RFID reader from a GUI (some code omitted)
; # Add Windows Tooltip-tray Options #
Menu, tray, tip, AutoRun
Menu, tray, NoStandard
Menu, tray, add, Variables
Menu, tray, add
Menu, tray, add, Exit
return
; # Generate GUI with Keypress (optional) #
CapsLock:: ; Use Capslock to initialize
Gui, add, Text,, Please insert the number of tests you will be making then press OK (Alt+O).
GUI, add, Edit, w400 vNumPass, 64 ; 64 is set as the default program runs
Gui, Add, Text,, Please insert the number of seconds between passes.
Gui, add, Edit, w400 vNumSec, 4 ; 4 seconds as default time per run
Gui, Add, Button, x180 y100 h30 w50, &OK
Gui, -Theme
Gui, Show,, Autorun
return
GuiEscape:
GuiClose: ; Handles closing the window
Gui, Destroy
return
ButtonOK: ; Sends the program towards the loop cycle.
Gui, Submit
Gui, Destroy
Goto Looping
return
Looping:
Loop %Numpass% {
WinActivate RFID_AutoTurn ; Set Arduino code as active window
WinWaitActive RFID_AutoTurn
Send ^+m ; Ctrl-Shift-M opens the Serial Moniter which restarts the Arduino command stream, sending a 'restart' signal (simpler than interpreting a serial command)
WinActivate MultiReader for Speedway
WinWaitActive MultiReader for Speedway
WinGetActiveStats, Title, Width, Height, x, y
ClickX := (Width - 150), ClickY := (y + 310)
Click %ClickX%, %ClickY% ; Clicks 'Start Test' to start the test.
CurrLoop := 0
SleepTime := NumSec*1000 + 1000
Sleep %SleepTime% ; Wait for current read + 1 sec
CurrLoop++
WinActivate MultiReader for Speedway
Send !fs ; Alt-F-S will open File>Save
WinWaitActive, Save Inventory History Data
;; Omitted code which saves the collected data automatically to a file
If (CurrLoop = Numpass) {
MsgBox, 260, Script Continuation, Would you like to restart this entire cycle?
IfMsgBox Yes
Goto Looping ; restarts the cycle if 'yes' is pressed.
return
IfMsgBox No
Goto Exit
return
}
}
return
; # Generate GUI when clicking the Tray Icon and choosing 'Variables' #
Variables:
Gui, Destroy
Gui, add, Text,, Please insert the number of tests you will be making then press OK (Alt+O).
GUI, add, Edit, w400 vNumPass, 64
Gui, Add, Text,, Please insert the number of seconds between passes.
Gui, add, Edit, w400 vNumSec, 4
Gui, Add, Button, x180 y100 h30 w50, &OK ; User Input section.
Gui, -Theme
Gui, Show,, Autorun
return
Exit:
ExitApp ; Exit will end the running script.
- Convert my wireless mouse into an error-free presentation tool by clicking the mouse wheel
toggle := 0
Blockinput, MouseMoveOff
Mbutton::
toggle := !toggle
if toggle = 1
BlockInput, MouseMove
else
BlockInput, MouseMoveOff
return
#if toggle = 1 ;
Wheelup::
Wheeldown::
return
Lbutton::Send {Right}
Rbutton::Send {Left}
I have many more such scripts, giving some of the following abilities:
- Screen Capture and save to a remote location (programmable test monitoring)
- Daily comparison of program versions to their online parent site, gets the latest version if newer
- Build a simple GUI front-end for exposing a common function for a legacy BASH-only noSQL database
- As part of a text-based captcha solver to capture the captcha and enter the solution (ML was done in a different language)
- Beat the socks off of the Cookie Clicker game
- Many more online examples
As you can see that there are not that many lines of code to write to perform a complex or interesting task. This is the strength of a windows-environment scripting language which acts as the user - it can do whatever you can!