preload
Mar 04

Ever wanted to have a spell check function in your Ruby Program? As long as you have MS Word installed, you can use the Spellcheck function from your program. Here’s the code:

require 'exo/iswindows'

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

require 'win32ole'

def spellcheck(scstring)
   word = WIN32OLE.new('Word.Application')
   doc = word.Documents.Add     ## Blank document

   word.Selection.Text = scstring
   word.Dialogs(828).Show

   ### return the corrected text
   if not scstring[/ /]      ## only one word with no spaces in the string
     # highlight the word first,
     word.Selection.MoveLeft( 'Unit'=>2,
            'Count'=> 1,
            'Extend'=>2)
   end
   ## multiple words end up already selected after the spell check
   # then retrieve.
   correct = word.Selection.Text
   doc.close(0)
   word.Quit
   return correct
end

if __FILE__ == $0
   puts "Corrected => #{spellcheck(ARGV[0])}"
end

The program opens a new document, pastes the text to check into the document, and then brings up the spellcheck dialog box with any words it can’t find in the dictionary and prompts you to correct the mistakes. Here’s an sample output:

C:\Server6\Dev\Ruby>ruby spellcheck.rb "this is a test srting to seee how the slpell check is working"
Corrected => This is a test string to see how the spell check is working

C:\Server6\Dev\Ruby>ruby spellcheck.rb  antidisestablishmenttarianism
Corrected => antidisestablishmentarianism

For some reason, if you check multiple words, the dialog auto-closes after the last ‘fix’ …but if its just one word, it stays open until you click the close button. Conversely, multiple words stay selected in the Word doc after the dialog closes, but with only one word, it does not stay selected, and you have to select it back in order to read it off the page of the document.

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

First off, let me say that there is not an original thought in any of this code, since it has all been taken from a number of different articles out on the Internet. The Daemonizing code was taken from the Active State Code Recipes area.

One of my customers has a number of database servers that we would like to monitor and see what the state of the clusters are. The problem is that the clustat command — that used to be run-able by everyone in a lesser version of RHEL — is now only usable by root in RHEL v5.3!. Not wanting to give out root access to everyone, we decided that a quick little custom server that provided the output of the clustat command in XML format would do the trick. Then I just wrote a Ruby program to query all the Clustat XML servers and display the results in a readable format. If there is enough interest, I can post a public version of that program.

Here’s the code: Continue reading »

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

When I want to distribute a Ruby script to a customer, sometimes its just easier to use something like Ocra to package up all the files needed into one nice .exe file that I can send over. Since I use Rake a lot, I wanted to figure out a way to automate the process. Here’s a simple example:

...
desc "List available Tasks"
task :default do
   sh %{ rake -T }
end

desc "Make BI_Competition_Status_Report.exe file"
task :exe do
   sh %{ cd lib && rake exe }
   sh %{ move lib\\BI_Competition_Status_Report.exe .}
end
...

This is in your main project Rakefile. Since I’m using NetBeans, it places my Ruby files in a ./lib directory. The first sh command simply CD’s down to lib, and runs a second Rakefile located there:

desc "Make BI_Competition_Status_Report.exe file"
task :exe do
   sh %{ ocra --windows --icon C:/Server12/Dev/Ruby/Exonets.ico BI_Competition_Status_Report.rb}
end

This is the actual Ocra command that packages up the Ruby app into a single .exe file. When this rake command ends, the last command in the previous Rakefile moves the completed .exe file up to the current directory.

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

Anyone who has ever worked with networks at one point or another always ends up running a telnet or ping command over and over again to generate traffic and check if one computer can talk to another. After running that command a couple dozen times, one starts to think that maybe it would be better to write a program to do this instead.

One of my customers has a number of RedHat servers that I’m not allowed to install any programing language like Ruby or Perl on that I would normally use to write such a program…however, they have a complete Python installation for some reason. Not to argue with fate, I wrote the following script to run my tests with:

#
# nettest.py
#
import sys
import socket
import time

host = sys.argv[1]
port = int(sys.argv[2])
# type => ["tcp" or "udp"]
type = sys.argv[3]
test = ""
if len(sys.argv) > 4 :
 test = sys.argv[4]

while 1 :
  if type == "udp":
    s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  else:
    s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  s.settimeout(5)
  try:
    if type == "udp":
      s.sendto("--TEST LINE--", (host, port))
      recv, svr = s.recvfrom(255)
      s.shutdown(2)
      print "Success connecting to " + host + " on UDP port: " + str(port)
    else:
      s.connect((host, port))
      s.shutdown(2)
      print "Success connecting to " + host + " on TCP port: " + str(port)
  except Exception, e:
    try:
      errno, errtxt = e
    except ValueError:
      print "Cannot connect to " + host + " on port: " + str(port)
    else:
      if errno == 107:
        print "Success connecting to " + host + " on UDP port: " + str(port)
      else:
        print "Cannot connect to " + host + " on port: " + str(port)
        print e
  if test != "C" :
    sys.exit(0)

  s.close
  time.sleep(1)

This is run like so: Continue reading »

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

I found it a bit odd that there doesn’t seem to be any tutorials on how to automate Microsoft Visio using Ruby. Most of the other Office apps have a bunch of pages on automation, but none on Visio….that or my Google Fu is leaving me ;)

So…. Here’s a brief tutorial on how to automate Visio using Ruby. First thing you need to do is bring in the WIN32OLE module and create a new instance of the Visio application

require 'win32ole'
visio = WIN32OLE.new('Visio.Application')

If you already have Visio running, you can connect to it with this line instead

visio = WIN32OLE.connect('Visio.Application')

Once you have your instance, its usually best to load in all the constants from the application. Visio has tons and tons, so if you are going to try and convert any VBA or C++ code over, you will need these.

class VisioConst
   # Empty class to hold constants
end
...
WIN32OLE.const_load(visio, VisioConst)

Be sure to put the class declaration below the ‘require’ statements so your code will read better. Now we will load in a Visio template just to make things easier on us. Continue reading »

SociBook del.icio.us Digg Facebook Google Yahoo Buzz StumbleUpon
Tagged with:
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 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 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: