preload
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: Continue reading »

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
Jan 15

Lucky me I got a new computer this week, and of course it comes with Windows 7. So I was installing all my development tools — Ruby and Watir among others — and ran into this problem:

C:\Users\John\Dev>gem install watir
Building native extensions.  This could take a while...
ERROR:  Error installing watir:
        ERROR: Failed to build gem native extension.

C:/Ruby/bin/ruby.exe extconf.rb
checking for strncpy_s()... no
creating Makefile

make
'make' is not recognized as an internal or external command,
operable program or batch file.

Gem files will remain installed in C:/Ruby/lib/ruby/gems/1.8/gems/win32-api-1.4.5 for inspection.
Results logged to C:/Ruby/lib/ruby/gems/1.8/gems/win32-api-1.4.5/ext/gem_make.out

C:\Users\John\Dev>

Hmm… Thats not good. Looking around on the Internet, I found that there was a devkit Continue reading »

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
Jan 05

Some of the systems that I need to get access to from programs are not available via the web proxy….but others are only available using the web proxy.  So I needed a way to turn the proxy on and off depending on which system I needed to connect to.  I did some digging around and came up with the following code:

require 'win32/registry'

def proxy_disable
   reg = Win32::Registry::HKEY_CURRENT_USER.open("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\",
             Win32::Registry::KEY_WRITE)
   reg.write("ProxyEnable", Win32::Registry::REG_DWORD, 0)
end

def proxy_enable
   reg = Win32::Registry::HKEY_CURRENT_USER.open("Software\\Microsoft\\Windows\\CurrentVersion\\Internet Settings\\",
             Win32::Registry::KEY_WRITE)
   reg.write("ProxyEnable", Win32::Registry::REG_DWORD, 1)
end
...
ie = Watir::IE.new
ie.goto("http://website_via_proxy.com/")
proxy_disable()
ie.goto("http://website_direct.com/")
proxy_enable()

You can also modify the proxy server by writing to “ProxyServer”, and change the exceptions list by writing to “ProxyOverride”.

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
Jan 04

One of my customers has a web proxy that handles things like timeout and bad DNS lookups. The problem I run into is that their proxy server does not pass back any HTTP error codes, only a very brief HTML page with the error. This precludes using the built-in HTTP error checking code (check_for_http_error)in Watir that I have used before.   Not wanting to rewrite a bunch of code, I just extended the Watir class to include a custom error check method:

require 'watir'
require 'timeout'
...
class Watir::IE
  def company_error?
    g = self.html[/\<BIG\>(Network Error .*)\<\/BIG\>/, 1]
    return g if g   ## if no error, g = nil
    return false
  end
end
...
url = "http://internal.company.com/page/"
ie = Watir::IE.new
begin
  Timeout::timeout(15) do
    ie.goto url
  end
rescue Exception => e
  # your timeout error code here
  exit
end
if ie.company_error?
  puts "ERROR: #{ie.company_error?}"
  exit
end

The method output looks like this:

irb(main):1683:0> test = "http://beblatt.blar"
=> "http://beblatt.blar"
irb(main):1684:0> ie.goto test
=> 0.658
irb(main):1685:0> ie.company_error?
=> "Network Error (dns_unresolved_hostname)"
irb(main):1686:0>

This catches any timeouts waiting to connect to the web page, and any of the custom proxy errors that could be returned. For ease of making the example code, it just exits on an error, but in the real world, I would take steps to recover or retry.

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with: