preload
Jan 31

I’ve been working with Visio lately and noticed that when my programs start it up, Visio was not coming up maximized. Since I wanted to be able to see my work full screen, I started looking for a way to force it to maximized mode. I quickly learned that there is no convenient ‘visio.Maximize’ method to use. Bummer. Other Office apps have a ‘.WindowState’ parameter that can be set to minimize, maxamize, restore, or hide the application window, but not Visio. Guess that would make it too easy ;)

For Visio, you can use the ‘ShowWindow’ function from the user32.dll to do the work:

require 'Win32API'

##Possible cmd values:
# Hidden => 0
# Restored => 1
# Minimized => 2
# Maximized => 3

def ShowWindow(wndHandle, cmd)
   wndShowWindow = Win32API.new("user32", "ShowWindow", ["p","i"], "i")
   wndShowWindow.call(wndHandle, cmd)
end

wndHandle‘ is the infamous Window Handle used in the lower-level Windows APIs. At least Visio has a way to return the handle. So in your program:
Continue reading »

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

One of my customers has these Cisco 4900M Switches and we had to figure out what the baud rate/stop bits/parity settings were. In the hopes that this one day helps some other Cisco IOS newbie, here’s how you find it:

Log into the switch, and at the command prompt, enter this command:

show line con 0

You should see something similar to this:
Continue reading »

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

With all those neat Wingdings characters available, its nice to be able to insert them into an Excel spreadsheet programatically. The easiest way to go about it is to Record a Macro of the character being inserted, then use the resulting VBA code as a reference for your Ruby code.

Working on a checklist application for a customer, I needed to insert checkmarks, and X-out characters into a column of the list. First step was to record the macro in Excel, then look at the resulting macro (To look at the macro in Excell 2003, click on Tools > Macro > Macros… then highlight the macro and click the ‘Edit’ button). For my checkmark, the code looked like this:

ActiveCell.FormulaR1C1 = "P"
    With ActiveCell.Characters(Start:=1, Length:=1).Font
        .Name = "Wingdings 2"
        .FontStyle = "Bold"
        .Size = 10
        .Strikethrough = False
        .Superscript = False
        .Subscript = False
        .OutlineFont = False
        .Shadow = False
        .Underline = xlUnderlineStyleNone
        .ColorIndex = xlAutomatic
    End With
    Range("I23").Select

So for my insertCheckmark function, my code looks like this:
Continue reading »

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

Over at the Ruby on Windows blog, David posted an article about how the latest versions of Office allow for saving files as PDF. Which prompted me to ask how you can find out what the versions are, since Office 2003 apps don’t have this option. So in between watching the AFC Championship game, I figured it out and came up with the following program:

require 'win32ole'

xl = WIN32OLE.new('Excel.Application')
xl.visible = false

ver = nil
case xl.Version
   when "12.0"
     ver = "Excel 2007"
   when "11.0"
     ver = "Excel 2003"
   else
     ver = "{Unknown Version => #{xl.Version}}"
end
puts "     Excel Version: #{ver}"
xl.Quit

word = WIN32OLE.new('Word.Application')
word.visible = false
ver = nil
case word.Version
   when "12.0"
     ver = "Word 2007"
   when "11.0"
     ver = "Word 2003"
   else
     ver = "{Unknown Version => #{word.Version}}"
end
puts "      Word Version: #{ver}"
word.Quit

ppt = WIN32OLE.new('Powerpoint.Application')
#ppt.visible = false    ## Powerpoint 2007 does not allow itself to be hidden?!?
ver = nil
case ppt.Version
   when "12.0"
     ver = "Powerpoint 2007"
   when "11.0"
     ver = "Powerpoint 2003"
   else
     ver = "{Unknown Version => #{ppt.Version}}"
end
puts "Powerpoint Version: #{ver}"
ppt.Quit

ol = WIN32OLE.new('Outlook.Application')
#ol.visible = false
ver = nil
## Outlook seems to tack on a build number
tt = ol.Version.slice(0,4)
case tt
   when "12.0"
     ver = "Outlook 2007"
   when "11.0"
     ver = "Outlook 2003"
   else
     ver = "{Unknown Version => #{ol.Version}}"
end
puts "   Outlook Version: #{ver}"
ol.Quit
SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
Jan 17

Lately I’ve been using Behavioral-Driven Design (BDD) principals in developing custom software for my customers. As part of that, I have been using the RSpec gem in Ruby to test my developing software. The ’spec’ program has a very nice HTML output option that will show in a hurry if my tests passed or not:
RSpec output
To create this output though, I had to run the program, then try and open the output file in my web browser. Thinking there was a better way to do this, I created the following program:
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 11

I’m not sure if I picked this up from another website or not, but its been in my bag of tools almost as long as I’ve been programming in Ruby :)

#!c:\ruby\bin\ruby.exe -w

require 'exo/iswindows'

def which(pgm)
   @path = ENV['PATH'].split(/;/)
   @path.each { |cdir|
      cmd = cdir + "\\" + pgm
      if test(?s, cmd)
        return cdir
      end
    }
  return nil
end

if __FILE__ == $0
   aa = ARGV[0]
   if RUBY_PLATFORM.isWindows?
     if (! aa.index("."))
       aa += ".exe"
     end
   end

   rc = which(aa)
   if (rc)
     print rc
   else
     print "NOT FOUND in PATH=" + ENV['PATH']
   end
end

Put the which.rb file in the path somewhere and it works the same way as the unix command of the same name:
Continue reading »

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

One project that I’m currently working on calls for taking tasks out of a MS Project document and moving them to a Powerpoint presentation with pretty formatting. Maybe I’ll blog about the whole thing later.  Here’s a quick program I wrote to dump out all the tasks from a test project in a somewhat formatted output to verify I could actually get the tasks:

#!C:\ruby\bin\ruby.exe

require 'exo/iswindows'

if !RUBY_PLATFORM.isWindows?
   puts "This program only runs under Windows!"
   exit
 end

require 'win32ole'

def fmtMSProjDate(msdate)
   yr = msdate[/^(\d\d\d\d)\/\d\d/, 1]
   mth = msdate[/^\d\d\d\d\/(\d\d)\/\d\d/, 1]
   day = msdate[/^\d\d\d\d\/\d\d\/(\d\d) /, 1]
   return "#{mth}/#{day}/#{yr}"
end

def getAbsolutePathName(file)
   fso = WIN32OLE.new('Scripting.FileSystemObject')               ## VBA File System commands
   return fso.GetAbsolutePathName(file)
end

if !ARGV[0][/\:/]
  file = "#{Dir.pwd}/#{ARGV[0]}"
else
  file = ARGV[0]
end

app = WIN32OLE.new('MSProject.Application')
app.FileOpen(getAbsolutePathName(file))
pj = app.ActiveProject
#app.Visible = true

puts "\nProject: #{pj.Title.ljust(60)}" + fmtMSProjDate(pj.Start.to_s) + "  " + fmtMSProjDate(pj.Finish.to_s) + "\n\n"

pj.Tasks.each do |t|
   puts t.ID.to_s.rjust(5) + " " + "| "*t.OutlineLevel + t.Name.ljust(63-(t.OutlineLevel*2)) + fmtMSProjDate(t.Start.to_s) + "  " + fmtMSProjDate(t.Finish.to_s)
end

app.Quit

Here’s my test run:
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: