preload
Resetting the Oil Change light on a 2007 Saturn VUE Adding HTML Copy support to Win32::Clipboard in Ruby
Mar 16

If you try to “compile” a Ruby script that has the Watir gem in it with OCRA, you will find that running the compiled .exe file on a computer without the Watir gem previously being installed may result in this error:

c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie.rb:113:in `initialize': unknown OLE server: `AutoItX3.Control' (WIN32OLERuntimeError)
    HRESULT error code:0x800401f3
      Invalid class string      from c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie.rb:113:in `new'
        from c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie.rb:113:in `autoit'
        from c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:425:in `autoit'
        from c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:422:in `set_window_state'
        from c:/ruby/lib/ruby/gems/1.8/gems/watir-1.6.2/lib/watir/ie-class.rb:398:in `maximize'
        ...

Huh? Why am I getting a WIN32OLE error? This all runs fine on my computer when I tested it! … Well, it seems that Watir uses its own version of a win32ole gem, and not the one that you already have installed. In fact, when you compile a Ruby script that has both win32ole and watir gems, you will need to comment out the “require ‘win32ole’” line in order for it to work. Anyway… as part of the win32ole gem install, it seems that it registers the AutoItX3.dll file into the registry. OCRA will, however, *NOT* copy this file over and register it for you, so you may see the error above.

So…the trick is add the AutoItX3.dll file to your OCRA compile, and to temporarily register the DLL before calling watir or win32ole commands. I simply copied the DLL from the win32ole gem directory to my Ruby script’s working directory, and then added it to my OCRA compile command:

C:\Server4\Dev\MyProg>ocra --console --icon c:/Server4/Dev/icons/exonets.ico myprog.rb AutoItX3.dll

OCRA will add the DLL to the EXE and when run will place it in the current temporary directory. After that you need to run the DLL register command to make it an OLE server, then when done, be sure to unregister it before your program completes.
Here a sample of code that I use to accomplish all this:

#!C:\ruby\bin\ruby.exe -W0
#
# Using the two lines below generates a lot of warning messages that I don't
# want my clients to see, so hence I use the '-W0' parameter above to
# suppress warning messages
#
require 'watir/win32ole/win32ole'
require 'watir'
#require 'win32ole'

class MyClass
   VERSION = '0.1d'
   @@autoitx = false   ## had to register AutoItX3.dll, so unregister at program end!!

   def initialize()
      header()
      ensureAutoItX3()
      ...
      trap("INT") do
         ensureProgramEnd()
         exit
      end
   end
   ...
end

def ensureAutoItX3
   begin
     test = WIN32OLE.new('AutoItX3.Control')
   rescue
     cwd = File.dirname(__FILE__).gsub(%r{/}) { "\\" }
     if File.exists?("#{cwd}\\AutoItX3.dll")
        system("regsvr32 /s #{cwd}\\AutoItX3.dll")
        @@autoitx = true
     else
        puts "Unable to find AutoItX3.dll -- Aborting!!"
        exit
     end
   end
end

def ensureProgramEnd
   ##
   ## Code we want to be sure runs at the end of the program, or if we
   ## get aborted!!
   ##
   if @@autoitx
      cwd = File.dirname(__FILE__).gsub(%r{/}) { "\\" }
      system("regsvr32 /u /s #{cwd}\\AutoItX3.dll")
   end
end

Keep in mind that since you are using an OCRA compile, your current directory is not the same as where you launched your program from, so you need to extract the temp directory from the ‘__FILE__’ builtin variable, as that is where your DLL file is. As with any OCRA program, its always a good idea to trap Ctrl-C escapes to ensure that you have a normal ‘exit’ out of your Ruby program so that the temporary directory can be erased and not leave a bunch of Ruby source code on the user’s computer.

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon

3 Responses to “Successfully using OCRA with Watir”

  1. Gary Says:

    thank you, this post is very helpful to me .

  2. pejte Says:

    Excellent post, you are being really helpful.

  3. Scatman Dan Says:

    Incredibly helpful post, thanks! I’m not dealing with this exact same problem (although I will be later this week) but with a similar one, and your pointers set me in the right direction. Thanks!

Leave a Reply