I am trying to build an windows service ( WIN XP SP-2) using the
Win32-service package for ruby.

This service  is supposed to  pull some stock data from yahoo site
every minute and print to screen.

For this objective to be accomplished  i have the following three files

1> yahootickerpull.rb

This has a class Yahooticker and a method called refresh.

2> datasrc_ctl.rb

This has code for controlling the service like
install,start,stop,delete etc..... Here i utilize the win32/service

3>yahootickerservice.rb

Here i require the yahootickerpull  and win32/service ... and override
the "Daemon" class onto "YDaemon" class .
In the "service_init" method i create a Yahooticker object .... and in
the service_main method i call the refresh method of this object.


This is the blue print.
===============================

problem is  i get an error:

C:\mooney.com\historicalqoute\yahooticker>ruby datasrc_ctl.rb start
VERSION: 0.5.2
datasrc_ctl.rb:61:in `start': The service did not respond to the start
or control
request in a timely fashion. (Win32::ServiceError)
        from datasrc_ctl.rb:61

==================================

I suspected the win32/service ....  but the example code that comes
with the package  tdaemon.rb and tdaemon_ctl.rb...... works perfectly
....

So i suppose i am doing some fundamental mistakes....

1>1>1>1>1>=======yahootickerpull.rb
============================================
require 'open-uri'
require 'ostruct'
require 'csv'
require 'yaml'
require 'mysql'
include Enumerable
class Yahooticker

SOURCE_URL = "http://finance.yahoo.com/d/quotes.csv"

#These are the symbols I understand, which are limited
OPTIONS = {
:symbol=>"s",
:name=>"n",
:last_trade=>"l1",
:last_trade_date=>"d1",
:last_trade_time=>"t1",
:open=>"o",
:high=>"h",
:low=>"g",
:high_52_week=>"k",
:low_52_week=>"j"
}

def initialize(symbols, options = [:symbol, :name,
:last_trade, :last_trade_date,
:last_trade_time])
@symbols = symbols
@options = options
@data = nil
end

def each
data.each do |row|
struct = OpenStruct.new(Hash[*(@options.zip(row).flatten)])
yield struct
end
end

def each_hash
data.each do |row|
hash = Hash[*(@options.zip(row).flatten)]
yield hash
end
end

def refresh
#p @symbols.to_s
symbol_fragment = @symbols.to_s.gsub(/\n/,'+')
#p "THE symbol: #{symbol_fragment}"
puts "============================"
option_fragment = @options.map{|s| OPTIONS[s] }.join ""
url = SOURCE_URL + "?s=#{symbol_fragment}&f=#{option_fragment}"
#puts "THE URL: #{url}"
@data = []
CSV.parse open(url,:proxy=>"http://127.0.0.1:8080").read do |row|

# this is where we will modify and put it in mysql database


p row
end
end

#def data
#refresh unless @data
#@data
#end

end
1>1>1>1>1>1>==================================
2>2>2>2>2>2>======datasrc_ctl.rb==================
#require 'yahootickerpull'
require 'win32/service'
include Win32

puts 'VERSION: ' + Service::VERSION

# I start the service name with an 'A' so that it appears at the top
SERVICE_NAME = 'AbbaSvc'
SERVICE_DISPLAYNAME = 'Abba'

cmd = 'c:\ruby\bin\ruby '
cmd += '"' + File.dirname(File.expand_path($0)).tr('/', '\\') +
'\yahootickerservice.rb' + '"'

raise ArgumentError, 'No argument provided' unless ARGV[0]

case ARGV[0].downcase
   when 'install'
      svc = Service.new
      svc.create_service{ |s|
         s.service_name = SERVICE_NAME
         s.display_name = SERVICE_DISPLAYNAME
         s.binary_path_name = cmd
      }
      svc.close
      puts 'Service ' + SERVICE_NAME + ' installed'
   when 'start'
      if Service.status(SERVICE_NAME).current_state != 'running'
          #@portfolio=[]
          #@portfolio=IO.readlines('c:\mooney.com\teststock.txt')
          #options=[:symbol, :name, :open, :high , :low]
          #@tick = Yahooticker.new(@portfolio,options)
          #@tick.refresh
         Service.start(SERVICE_NAME)
         while Service.status(SERVICE_NAME).current_state != 'running'
            puts 'One moment...' +
Service.status(SERVICE_NAME).current_state
            sleep 1
         end
         puts 'Service ' + SERVICE_NAME + ' started'
      else
         puts 'Already running'
      end
   when 'stop'
      if Service.status(SERVICE_NAME).current_state != 'stopped'
         Service.stop(SERVICE_NAME)
         while Service.status(SERVICE_NAME).current_state != 'stopped'
            puts 'One moment...' +
Service.status(SERVICE_NAME).current_state
            sleep 1
         end
         puts 'Service ' + SERVICE_NAME + ' stopped'
      else
         puts 'Already stopped'
      end
   when 'uninstall', 'delete'
      if Service.status(SERVICE_NAME).current_state != 'stopped'
         Service.stop(SERVICE_NAME)
      end
      while Service.status(SERVICE_NAME).current_state != 'stopped'
         puts 'One moment...' +
Service.status(SERVICE_NAME).current_state
         sleep 1
      end
      Service.delete(SERVICE_NAME)
      puts 'Service ' + SERVICE_NAME + ' deleted'
   when 'pause'
      if Service.status(SERVICE_NAME).current_state != 'paused'
         Service.pause(SERVICE_NAME)
         while Service.status(SERVICE_NAME).current_state != 'paused'
            puts 'One moment...' +
Service.status(SERVICE_NAME).current_state
            sleep 1
         end
         puts 'Service ' + SERVICE_NAME + ' paused'
      else
         puts 'Already paused'
      end
   when 'resume'
      if Service.status(SERVICE_NAME).current_state != 'running'
         Service.resume(SERVICE_NAME)
         while Service.status(SERVICE_NAME).current_state != 'running'
            puts 'One moment...' +
Service.status(SERVICE_NAME).current_state
            sleep 1
         end
         puts 'Service ' + SERVICE_NAME + ' resumed'
      else
         puts 'Already running'
      end
   else
      raise ArgumentError, 'unknown option: ' + ARGV[0]
end
2>2>2>2>2>2>=========================================================
3>3>3>3>3>3>===========yahootickerservice.rb====================================
require 'yahootickerpull'
require 'win32/service'
include Win32

LOG_FILE = "C:\\test.log"

begin
   class YDaemon < Daemon
      def service_init
         @portfolio=[]
         @portfolio=IO.readlines('c:\mooney.com\teststock.txt')
         options=[:symbol, :name, :open, :high , :low]
         @tick=Yahooticker.new(@portfolio,options)
         sleep 2
      end

      def service_main
         msg = 'service_main entered at: ' + Time.now.to_s
         File.open(LOG_FILE, "a+"){ |f| f.puts msg }

         while running?
            if state == RUNNING
               @tick.refresh
               sleep 60
            else
               sleep 0.5
            end
         end

         File.open(LOG_FILE, "a+"){ |f| f.puts "STATE: #{state}" }

         msg = 'service_main left at: ' + Time.now.to_s
         File.open(LOG_FILE, "a+"){ |f| f.puts msg }
      end

      def service_stop
         msg = "Received stop signal at: " + Time.now.to_s
         File.open(LOG_FILE, "a+"){ |f| f.puts msg }
      end

      def service_pause
         msg = "Received pause signal at: " + Time.now.to_s
         File.open(LOG_FILE, "a+"){ |f| f.puts msg }
      end

      def service_resume
         msg = "Received resume signal at: " + Time.now.to_s
         File.open(LOG_FILE, "a+"){ |f| f.puts msg }
      end
   end

   YDaemon.new.mainloop
rescue Exception => err
   File.open(LOG_FILE, "a+"){ |fh| fh.puts 'Daemon failure: ' + err }
   raise
end
3>3>3>3>3>3>=============================================


sorry for a long post.

Thanks
rajib