Tag Archives: OLE

Ruby on Windows: OLE automation for Outlook – Shared calendars

Ruby has a nice library for OLE automation, win32ole. I used this library to get appointments from shared outlook (exchange) calendars. The scripts are testen on Windows Vista with Outlook 2003. This is how it works:

outlook_reader.rb

require 'win32ole'
outlook = WIN32OLE.new('Outlook.Application')
mapi = outlook.GetNameSpace('MAPI')

# this is explained later
Thread.new do
  system('outlook_clicker.exe')
end

# create a recipient and resolve him
myRecipient = mapi.CreateRecipient("John Doe")
myRecipient.Resolve

# get the shared calendar of the recipient
if myRecipient.Resolved
  calendar = mapi.GetSharedDefaultFolder(myRecipient, 9)
end

# write the calendar data to the output
if calendar
  calendar.Items.each do |item|
    puts "#{item.Start} - #{item.End}: #{item.Subject}"
  end
end

Outlook has a mechanism which should protect the outlook data from unauthorized access, e.g. viruses and trojans. Everytime you want to access the data from outlook a popup opens which asks you, if the access should be granted. In case of automation this is very bad, because you usually don’t want to click anything if you automate a process.

So here the solution. I’ve created a ruby script which clicks the dialog for the user. Then I converted it into an executeable using RubyScript2exe (Ruby code gets compiled).

outlook_clicker.rb

require 'win32ole'

# new shell object
wsh = WIN32OLE.new('Wscript.Shell')

# for timeout management
time_out = 0
time_out_max = 10
interval = 0.01

# try to activate the window with the Title 'Microsoft Office Outlook'
while !wsh.AppActivate('Microsoft Office Outlook') do
  time_out = time_out + interval
  sleep(interval)
  if time_out > time_out_max
    Process.exit!
  end
end

# if the popup exists and the timeout is not reached some
# keys get send to the popup
wsh.SendKeys("{TAB}")
wsh.SendKeys("{TAB}")
wsh.SendKeys(" ") # this is "space"
wsh.SendKeys("{TAB}")
wsh.SendKeys("{TAB}")
wsh.SendKeys("{ENTER}")

To compile this ruby file into an executeable rubyscript2exe can be used. To install it you can use Ruby Gems (command prompt):

gem install rubyscript2exe

After installing you can open a command prompt, change to the directory your scripts are in and compile the clicker using the following command

ruby rubyscript2exe.rb outlook_clicker.rb

The executable will be created in the same directory. In the file outlook_reader.rb the following lines call the outlook_clicker.exe:

Thread.new do
  system('outlook_clicker.exe')
end

In this three lines a new thread is created which calls the outlook_clicker.exe using the system method. Basically we reached that both scripts are executed in parallel.

If you execute the outlook_reader.rb you can see that the popup shortly opens and then automatically gets closed.

Recommend reading: http://rubyonwindows.blogspot.com/