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.







June 7th, 2010 at 3:15 am
thank you, this post is very helpful to me .
July 2nd, 2010 at 4:38 am
Excellent post, you are being really helpful.