Automating tasks in Windows

Introduction

This article was started in August 2009 by comparing AutoHotKey (AHK), AutoIt, WinBatch, and KixStart but it might include other solutions later on.

AutoIT vs. AutoHotKey?

AutoIt was first released in 1999, with a lot of the syntax and ideas coming from ScriptIt, a Microsoft project itself based on WinBatch.

The core of AHK was written from scratch, but includes some AutoIt3 code to implement some commands.

The AutoIt community feels that the AHK author didn't give enough credit when forking the code, and since then, no love is lost from the AutoIt community towards AHK.

AutoIT…

AHK…

More infos:

AutoIt

Learning

Help

https://www.autoitscript.com/forum/

?s

No PDF or CHM for tutorial? https://www.autoitscript.com/autoit3/docs/

How to handle time out? WinWaitActive("- Task", "",10)

Timeout = seconds or ms?

How to prevent compiling if undeclared variables?

Compile vs Build vs Go? No way to get Scite to run compiled app?

WinWaitActive() vs. WinWaitActivate()?

Getting Started

In addition to the online docs, wiki, the CHM files, and the forum, information can also be found in Learning To Script with AutoIt V3, AutoIT 1-2-3, and O'Reilly's AutoIt v3: Your Quick Guide by Andy Flesner.

As of version 3.3.6.1, AutoIT consists in the following programs:

To tell Scite where to locate the user's include files: Tools > SciTe Config

Sample code

It's a good idea to set the following option in all scripts: Opt('MustDeclarVars', 1)

Accessing Outlook

COM

$oOutlook = ObjCreate("Outlook.Application")

OutlookEX UDF

https://www.autoitscript.com/forum/topic/126357-outlookex-udf-help-support/

After installing OutlookEX UDF per its Readme, run Outlook, and use the following script to read the data from its To-Do List panel, sorted through Last Modified:

#include "OutlookEX.au3"

Global $oOutlook = _OL_Open()

If @error <> 0 Then Exit MsgBox(16, "OutlookEX UDF", "Error creating a connection to Outlook. @error = " & @error & ", @extended = " & @extended)

$aFolder = _OL_FolderAccess($oOutlook, "", $olFolderToDo)

Global $aResult = _OL_ItemFind($oOutlook, $aFolder[1], $olTask, "", "", "", "EntryID,Subject,LastModificationTime")

If @error Then

    MsgBox(16, "OutlookEX UDF - _OL_ItemSearch Example Script", "Error running _OL_ItemSearch. @error = " & @error & ", @extended = " & @extended)

Else

    _Arraydisplay($aResult)

EndIf

_OL_Close($oOutlook)

Editing Contacts in Outlook
  1. Download and unzip the latest release of OutlookEx UDF (help thread and wiki)
  2. Copy OutlookEX.au3 and OutlookEXConstants.au3 into AutoIt3\Include
  3. If using the Scite editor, copy au3.user.calltips.api into AutoIt3\SciTE\api (append if file already exists), and copy au3.userudfs.properties into AutoIt3\SciTE\properties (ditto)
  4. Launch Outlook
  5. Run this code:

To use control keys

;CTRL+A

Send("^a")

Sleep(3000)

;CTRL+C

Send("^c")

To set/get clipboard contents

#include <Constants.au3>

#include <MsgBoxConstants.au3>

#include <Date.au3>

ClipPut(_NowTime())

Local $sClipboard = ClipGet()

MsgBox($MB_SYSTEMMODAL, "Clipboard", $sClipboard)

How to interact with controls

Besides the Control*() functions, there are also: StatusbarGetText, WinActivate, WinGetClassList, WinMenuSelectItem.

ControlSend("Untitled - Notepad", "", "[CLASSNN:Edit1]", "This is some text")

ControlSetText("My Window", "", "[NAME:textBoxFolder]", "C:\Some\Folder")

ControlClick("My Window", "", "[ID:254]")

ControlClick("My Window", "", "[CLASS:Button; TEXT:Finish; INSTANCE:2]")

Note: ControlSetText() sometimes doesn't work as expected; If that case, try ControlSend() instead.

To record an action

Go to \Extras\Au3Record\, and launch Au3Record.exe to record an action that Au3Record will then save as source code that you can use in your scripts.

Caution: Code generated Au3Record isn't always reliable, as some functions won't work. YMMV.

Note: _WinWaitActivate() is not part of AutoIT; Its code found below must be included in the script.

Note: "AutoIt Recorder utility is not available from AutoIt Version 3.3.14.1." (source)

CHECK To have Au3Record generate all the code, you have to start the AU3Record program from inside SciTE, with an AutoIt script open in it, or start the recorder with the /o option to get that checkbox to appear.

To edit a script

Launch the SciTE editor in install\SciTe\SciTE.exe, where you can copy-paste the action you just recorded with Au3Record.exe.

To find information about a window

Use install\Au3Info.exe.

Difference between native WinWaitActive() and external _WinWaitActivate()?

In SciTE-Lite's Tools menu, what's the difference between Compile and Build?

Why doesn't Scite-Lite Compile/Build find syntax errors such as missing closing bracket?

For/Next Loop

For $i = 5 To 1 Step -1

    MsgBox($MB_SYSTEMMODAL, "", "Count down!" & @CRLF & $i)

Next

To comment a line

Use ";"

To comment a block of text

#comments-start

#comments-end

If using the AutoIT-provided SciTE editor, select the block of text, and hit Edit > Stream Comment

To display a messagebox

MsgBox(64, "My title", "My text")

Locating a window with partial text

Note: You may use Opt() as an alternative to AutoItSetOption().

AutoItSetOption ("WinTitleMatchMode",2)

Opt("WinTitleMatchMode", 1) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase

To handle time-out when a window doesn't show

Func _WinWaitActivate($title,$text,$timeout=0)

        $result = WinWait($title,$text,$timeout)

        if $result = False Then

                MsgBox(16,"Bad...","Window not displayed")

                Exit(1)

        EndIf

 

        If Not WinActive($title,$text) Then WinActivate($title,$text)

        WinWaitActive($title,$text,$timeout)

EndFunc

To pause for a few seconds

Sleep(1000) ; sleep for 1s

To move the mouse at the center of the screen

#include <Misc.au3>

CHECK MouseMove(@DesktopWidth/2, @DesktopHeight/2)

To send keys to window/control

http://www.autoitscript.com/autoit3/docs/functions/ControlClick.htm

http://www.autoitscript.com/autoit3/docs/functions/ControlCommand.htm

http://www.autoitscript.com/autoit3/docs/functions/ControlSend.htm

http://www.autoitscript.com/autoit3/docs/functions/ControlFocus.htm

(only as last resort)

http://www.autoitscript.com/autoit3/docs/functions/Send.htm

http://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm

To find a window with just part of title/text

Opt("WinTitleMatchMode", 1) ;1=start, 2=subStr, 3=exact, 4=advanced, -1 to -4=Nocase

More information here.

To put the focus on combobox

 

Variables

To set or refer to the content of a variable: (Const/Global/Local/Dim) $myvar = "test"

To refer to environment variables: @ComputerName

To require explicit declaration of variables: Opt("MustDeclareVars", 1)

Including files

To include files: #include <myfile.au3>

To include an external file into the AutoIT output EXE à la NSIS: FileInstall(Source,Destination[,flag])

UDFs

The array.au3 UDF offers extended functions to handle arrays, eg. _ArrayDisplay($myarray)

Loops

For $index=1 to 1

Next

Pausing

To pause for one second:

Exiting

Exit

Exit(1)

Exit(2)

Using SQLite

Source

#include <SQLite.au3>

#include <SQLite.dll.au3>

Global $DB

_SQLite_Startup ()

$DB = _SQLite_Open("sqlite.db")

_SQLite_Exec($DB, "CREATE TABLE TABLE1 (Text);")

_SQLite_Exec($DB, "BEGIN;")

For $i = 1 to 1000 Step 1

    _SQLite_Exec($DB, "INSERT INTO TABLE1 VALUES ('Some text');")

Next

_SQLite_Exec($DB, "COMMIT;")

_SQLite_Close($hDatabase)

_SQLite_Shutdown()

Source

#include <Array.au3>

#include <SQLite.au3>

 

_SQLite_Startup() ; Load the DLL

If @error Then Exit MsgBox(0, "Error", "Unable to start SQLite, Please verify your DLL")

 

Local $sDatabase = @ScriptDir & '\SQLiteTestDatabase.db'

Local $hDatabase = _SQLite_Open($sDatabase) ; Create the database file and get the handle for the database

 

_SQLite_Exec($hDatabase, 'CREATE TABLE People (first_name, last_name);') ; CREATE a TABLE with the name "People"

_SQLite_Exec($hDatabase, 'INSERT INTO People VALUES ("Timothy", "Lee");') ; INSERT "Timothy Lee" into the "People" TABLE

 

Local $aResult, $iRows, $iColumns ; $iRows and $iColuums are useless but they cannot be omitted from the function call so we declare them

 

_SQLite_GetTable2d($hDatabase, 'SELECT * FROM People;', $aResult, $iRows, $iColumns) ; SELECT everything FROM "People" TABLE and get the $aResult

_ArrayDisplay($aResult, "Results from the query")

 

_SQLite_Close($hDatabase)

_SQLite_Shutdown()

Desktop shortcut

To run a desktop shortcut:

Gotchas

Send() can't identify a window

The Send() function sends a string to whatever window is active, ie. it's not possible to tell it to only send data to a specific window. So if you're using a loop, add a WinWaitActive() to make sure you're no sending stuff in a totally different window:

AutoItSetOption("SendKeyDelay",0)
for $index = 1 to $pages
    ;Just to make sure we are sending keystrokes to the right window
    WinWaitActive("Acme - Iron")
 
    Send("^l")
    Sleep(500)
 
    $url = "http://www.acme.com/search.php?page=" & $index & "{ENTER}"
    Send($url)
 
    ;Wait 5s. There might be a better way to check that page download has completed
Sleep(5000)
Next

Concatenating strings

You must use "&", not "+":

$myvar = "First line " & @CRLF & "Second line"

Clipboard

Here's how to clear the clipboard, and copy data to it:

#include <Clipboard.au3>

StringRegExp

The PCRE regex engine that AutoIT uses is single-line by default. If you need to find a pattern in a multi-line string, you must tell PCRE explicitely:

"$array = StringRegExp($data, "(?mi)^(\d+) some text", 3)".

There is apparently no way to configure PCRE externely for the duration of a script, ie. without adding settings to every single pattern.

Here's how to extract the second part in a two-item string with a TAB delimiter:

$array = StringRegExp("John" & @TAB & "123", "\t(\d+)', 1)
for $i = 0 to UBound($array) - 1
    msgbox(0, "Items found", $array[0])
Next

GUI

AutoIT can be used to write graphical applications. As of 2018, there are two ways to do this: Either by writing your own code directly, or by using any of the numerous GUI creators such as the Koda GUI designer.

Q&A

What's the difference between a window title and a window text?

Script built with Au3Record.exe doesn't run

myscript..au3 (1) : ==> Unknown function name.: _WinWaitActivate("classname=TfrmPref","")

If you just copy/paste the output instead of what's actually saved in a file, you'll be missing some User-defined functions (UDF) that Au3Record relies on:

#region --- Internal functions Au3Recorder Start ---
Func _Au3RecordSetup()
        Opt('WinWaitDelay',100)
        Opt('WinDetectHiddenText',1)
        Opt('MouseCoordMode',0)
EndFunc
 
Func _WinWaitActivate($title,$text,$timeout=0)
        WinWait($title,$text,$timeout)
        If Not WinActive($title,$text) Then WinActivate($title,$text)
        WinWaitActive($title,$text,$timeout)
EndFunc
 
_AU3RecordSetup()
#endregion --- Internal functions Au3Recorder End ---

Script built with Au3Record.exe can't find application window

There is a bug with release 3.3 which uses "classname=myclass" instead of "[CLASS:myclass]".

AutoHotKey

Getting and displaying clipboard

Clipboard =

Send ^a

Send ^c

Stuff := Clipboard

MsgBox, Some title`n%Stuff%

Working with SQLite

;Download the sqlite3.dll and store it in the script's folder

 

;Download the following AHK include file from the AHK forum

#Include Class_SQLiteDB.ahk

 

MyDB := New SQLiteDB

MyDB.OpenDB("dummy.sqlite")

MyDB.Exec("CREATE TABLE IF NOT EXISTS MyTable (id INTEGER, data TEXT)")

MyDB.Exec("INSERT INTO MyTable VALUES (55, 'blablah')")

MyDB.CloseDB()

Winbatch

http://www.windowware.com

Why choose Winbatch?

KixStart

http://en.wikipedia.org/wiki/KiXtart

Why choose KixStart?

Resources