Introduction to AutoItX3

I don’t know about you, but I’m constantly using Ruby to automate my work around the office. If I need a series of documents converted to another format, some data sorted out in a complex way, or even entering data into a web form, I’m usually doing it with Ruby.

Ruby can plug into other programs on Windows using OLE (Object linking & embedding), which allows it to send messages to other programs. For instance, here’s the Ruby code needed to open an instance of Microsoft Word, have it open every .doc file in a folder, and then close them:

require 'win32ole'
word = WIN32OLE.new "word.application"
Dir.glob("my_documents/*.doc").each do |doc|
  word.Documents.Add doc
  word.ActiveDocument.Close
end
word.Quit

And that’s all there is to it!

You may have noticed that I called all of the OLE methods with a capitalized first letter. In some cases, the name of an OLE method may conflict with the name of a regular Ruby method. For instance, if an OLE enabled program has a method named “send” then instead of calling the OLE method, you’d actually end up calling Ruby’s default send method that all objects have. You can avoid the problem by calling OLE methods with capitalized letters, which will never conflict with Ruby’s built in methods.

Ruby as the Ultimate Glue Language

There are lots of other things you can do with OLE, including controlling any MS Office application, most web browsers, and a whole slew of other programs. As you can imagine, it’s very powerful stuff to be able to script these programs from Ruby.

However, even the best OLE enabled programs tend to leave me wanting to be able to do something that the designers didn’t account for. That’s where AutoItX3 comes in.

AutoItX3 is a programming language that was made specifically to automate Windows. You can find it here: http://www.autoitscript.com/autoit3/index.shtml

If you need to automate something, it’s usually best to use the OLE interface when possible. AutoItX3 is a generalized tool, but a program’s OLE interface was created with that program in mind. However, when the OLE interface leaves you in need of more functionality, AutoItX3 can usually take care of whatever you need.

Where AutoItX3 Went Wrong

(And why it doesn’t matter)

Now, you may have noticed a problem with AutoItX3; it’s syntax looks like Visual Basic! I don’t know about you, but I stopped programming in Basic a long time ago, and I’d rather not start again. AutoItX3 has static variable typing, a lack of blocks, and all sorts of other things that make us love Ruby so.

Fortunately, the people who made AutoItX3 were not only bright enough to make this awesome tool, they also gave it a great OLE interface. In other words, we can use the methods from AutoItX3, but control the logic with Ruby. You get virtually all the power of AutoItX3, but only a tiny learning curve.

Keyboard Control to Major Tom

Have you ever wanted to make Ruby take control of your keyboard? Perhaps to log into some website that doesn’t support cookies or something? Here’s how it goes in AutoItX3 (Via Ruby):

require 'win32ole'
ai = WIN32OLE.new("AutoItX3.Control")
1.upto(10) do |i|
  ai.Send "#{i}{ENTER}"
end

This script will print 1 through 10, pressing the Enter key after each number. AutoItX3 handles special keys through a set of escapes which are placed between {}. A full listing of escapes can be found here: http://www.autoitscript.com/autoit3/docs/appendix/SendKeys.htm

There are also some shorthand escapes that don’t require curly brackets. For instance ^ is short for CTRL, so:

ai.Send "^c"

would type CTRL+C (AKA: the shortcut for the Copy command).

Three Blind Mice

Of course, it can also control your mouse:

ai.MouseClick("left", 50, 75)

The above code would perform a left-click at 50 pixels from the left of your screen by 75 pixels from the top. AutoItX3 can even automate your scrollwheel:

ai.MouseWheel("down", 10)

This will make your mouse scroll down 10 “clicks”. AutoItX3 can also drag, drop, and do just about anything else you can legally do with a mouse in most states.

Where Art Thou, Notepad?

AutoItX3 can also wait for a specific window to open before moving on. Consider the following code:

require 'win32ole'

ai = WIN32OLE.new("AutoItX3.Control")

ai.WinWaitActive("Untitled - Notepad")
ai.Send("Chunky bacon!")

This program would run, wait until the active window is named “Untitled – Notepad”, and then type out a message. This is great for handling popups.

The More Things Change…

Now let’s say you’re using AutoItX3, but you’ve run into a nasty problem. A program you’re automating has some step that takes a long time. It’s difficult to get AutoItX3 to know when the program has finished processing, because it doesn’t give any kind of programatic feedback.

You could compensate by building a set delay into your program, but you’re wasting time after the other program finishes processing. Even more severe, if the other program processes longer than expected, you’re program could resume processing before the other program is ready. When that happens, your program is probably going to eat flaming death.

Fortunately, AutoItX3 can deal with this. So long as something changes on the screen when the other program finishes processing, you can use AutoItX3′s PixelChecksum method to spot changes:

old_screen_checksum = ai.PixelChecksum(100, 100, 200, 200)

until ai.PixelChecksum(100, 100, 200, 200) != old_screen_checksum do
  sleep 0.1
end

The code above would take a 100 by 100 pixel checksum of the screen, and check 10 times per second to see if that area of the screen has changed.

There are many other things that AutoItX3 can do.  The documentation is quite decent, and the new abilities it gives Ruby are divine. Try it out and I’m sure you’ll be impressed.

About these ads

8 comments so far

  1. Jonathan on

    Im having problem geting the pixelchecksum code to work, it gives no error but, just hangs there, nothing happens.. have you had this problem ?

  2. ActsAsBuffoon on

    The following code worked for me:

    * * * * * * * * * * * * * * * * * * * * * *

    require ‘win32ole’

    ai = WIN32OLE.new(“AutoItX3.Control”)

    old_screen_checksum = ai.PixelChecksum(100, 100, 200, 200)

    until ai.PixelChecksum(100, 100, 200, 200) != old_screen_checksum do
    sleep 1
    puts “Waiting…”
    end

    puts “Something moved!”

    * * * * * * * * * * * * * * * * * * * * * *

    Run the above code and then drag an open window through the upper left hand corner of your screen.

    Alternatively, try loading a video up on YouTube and setting the screen coordinates over the video.

    Once something changes in that area of the screen, the program should output “Something moved!” and terminate.

    Also, you may have made a mistake that I once made while goofing around with AutoIt. I tried to launch a program from the command line by using Ruby’s build in “system” command. So I wrote something like “system(‘notepad.exe’)”, and them my program froze. What I forgot, is that ruby’s execute waits for the command line to return before moving on. In other words, Ruby wasn’t going to execute the next statement until Notepad was closed.

    You can get around this by using AutoItX’s “ShellExecute” method, which will run the command and move on.

    If you’re still having an issue, then please feel free to post your code here and I’ll be happy to see if I can figure out what’s going on.

  3. Jonathan on

    I tried the code you posted and the samething happened again, I wrote in some debug puts like this
    ———————————————–
    require ‘win32ole’
    puts “1″
    ai = WIN32OLE.new(”AutoItX3.Control”)
    puts “2″
    old_screen_checksum = ai.PixelChecksum(100, 100, 200, 200)
    puts “3″
    until ai.PixelChecksum(100, 100, 200, 200) != old_screen_checksum do
    sleep 1
    puts “Waiting…”
    end

    puts “Something moved!”
    ————————————————
    it only gets to 2, I tried to call another autoitX function that moves the mouse and clicks, and it worked fine… :/ I run vista and ruby 1.8.6… its weird when I write a similar function in the autoit language it works fine :/ any ideas ?

  4. ActsAsBuffoon on

    That’s very odd. How old is your install of AutoItX3? I believe I’ve read that the PixelChecksum function had a bug in older versions.

    I’ve just tried running your code and it worked perfectly for me (After replacing the quotation marks. It looks like my blog software is taking some liberties with punctuation).

    My environment is Windows XP with Ruby 1.8.6 and AutoItX3 version 3.3.0.0. At least, that’s what the documentation for AutoItX3 says.

    If you’re running anything older than 3.3.0.0 for AutoItX3, then try updating. Let me know if that works.

  5. jonathan on

    Yes! that did it, it was the version of autoit :) I thought I had the latest version.. but alas I did not :P thanks a lot :)

  6. ActsAsBuffoon on

    Glad I could help :)

  7. automation on window « ai3x on

    [...] ruby and autoitx [...]

  8. Adhi on

    useful one.


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s

Follow

Get every new post delivered to your Inbox.

%d bloggers like this: