Alright, so here's what I've now been trying:

If I kill the external application that I'm using the OLE/COM
interface to talk to while my Ruby program is running, I get a
WIN32OLERuntimeError in my Ruby program.  Thus, since
Process.kill('KILL', <pid>) does seem to work on Windows (I did test
this), I figured I could make my timeout method look like this:

def timeout(sec, pid)
  begin
    watchdog = IO.popen "ruby -e 'sleep(#{sec});
Process.kill(:KILL.to_s, #{pid}) rescue nil'"
    yield
  ensure
    Process.kill('KILL', watchdog.pid) rescue nil
  end
end

and I could call it like this:

@sim = WIN32OLE.new 'PwrWorld.SimulatorAuto'
...
begin
  timeout(20, @sim.ProcessID) do
    @sim.RunScriptCommand('SolvePrimalLP()')
  end
rescue WIN32OLERuntimeError
  # rescue myself from the external application hanging up... i.e.
reinitialize @sim
end

However, it seems as though when creating the watchdog in the timeout
method IO.popen sometimes blocks execution.  I can't tell if it's due
to the external (OLE) application blocking or something else.  If I
don't use the timeout method the OLE application blocks at a different
time in the simulation, so I'm thinking it's not due to the OLE
application blocking...

Any ideas?!

--
Thanks!
Bryan