Hi all,

i detail out an issue i am facing while trying to read messages from
outlook via a windows service.

The goal of the code is to scan outlook inbox every 10 minutes and if
any specified  file attachment is found ... save it.

The code will be installed as an windows service and scan for the
email automatically.

The service code is fine and runs in background as well but as I call
outlook via  win32ole from the service mainloop it does not give me
the inbox with any item.


Can any one lead me to the problem??


the service code
 it works like a champ
================
require 'win32/service'
include Win32

puts 'VERSION: ' + Service::VERSION


SERVICE_NAME = 'Kpi-file-Scanner'
SERVICE_DISPLAYNAME = 'An-outlook-scanner'

cmd = 'c:\instantrails\ruby\bin\ruby'

cmd += '"C:\\instantrails\\rails_apps\\kpi\\vendor\\service\
\outlookpull.rb"'

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

case ARGV[0].downcase
   when 'install'


     svc= Service.new(SERVICE_NAME, nil,{
      :service_type       => Service::WIN32_OWN_PROCESS,
      :description        => SERVICE_DISPLAYNAME,
      :start_type         => Service::AUTO_START,
      :error_control      => Service::ERROR_NORMAL,
      :binary_path_name   => cmd,
      :load_order_group   => 'Network',
      :dependencies       => ['W32Time','Schedule'],
      :display_name       => 'Kpi-file-Scanner'}
      )


      puts 'Service ' + SERVICE_NAME + ' installed'
   when 'start'
      if Service.status(SERVICE_NAME).current_state != 'running'

         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
==============================================
now the outlookpull.rb code that is called by this service

===================================================
LOG_FILE = "C:\\instantrails\\rails_apps\\kpi\\vendor\\service\
\test.log"

begin
    require "C:\\instantrails\\ruby\\lib\\ruby\\gems\\1.8\\gems\
\actionpack-2.0.2\\lib\\action_controller.rb"
    require "C:\\instantrails\\rails_apps\\kpi\\app\\controllers\
\application.rb"
    require "C:\\instantrails\\rails_apps\\kpi\\app\\controllers\
\kpimumbai_controller.rb"
    File.open(LOG_FILE, "a+"){ |f| f.puts "kpimumbai_controller.rb
required" }
    require 'win32/service'
    require 'win32/daemon'
    include Win32
    require 'win32ole'
    require "parsedate.rb"
    include ParseDate

   class Daemon

      def service_init
         @a=KpimumbaiController.new
          sleep 10
      end

      def service_main
         msg = 'service_main entered at: ' + Time.now.to_s
         File.open(LOG_FILE, "a+"){ |f| f.puts msg }
         #@first_entry = true
         while running?
            if state == RUNNING
               msg = 'running state entered at : ' + Time.now.to_s
               File.open(LOG_FILE, "a+"){ |f| f.puts msg }
               begin
               #@tick.refresh(@first_entry,@sqlconnect)
               #@first_entry = false
                   #require 'win32ole'


               #we will get the time of the last parsed message and
               #will go in only if the message timing is after that of
the last parsed
               #message time
                   File.open(LOG_FILE, "a+"){ |f| f.puts "just before
readlines" }
                   last_time=IO.readlines("C:\\instantrails\\rails_apps
\\kpi\\vendor\\service\\spawntime.log")
                   last_time=last_time.to_s.chomp
                   File.open(LOG_FILE, "a+"){ |f| f.puts
"=====last_time:#{last_time}" }

                   if last_time.to_s == "nil"
                     last_time="1971/10/04 19:03:24"
                   end
                   @outlook = WIN32OLE.new('Outlook.Application')
                  @mapi = @outlook.GetNameSpace('MAPI')
                 @inbox = @mapi.GetDefaultFolder(6)
                 @file_c=1


                   arr_last_time =
parsedate(last_time.to_s).delete_if{|x|x=="nil"}

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

 
timed_last_time=Time.mktime(arr_last_time[0],arr_last_time[1],arr_last_time[2],arr_last_time[3],arr_last_time[4],arr_last_time[5])

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

                   File.open(LOG_FILE, "a+"){ |f|
f.puts"#{@inbox.UnreadItemCount}:Unread Messages" }
                   File.open(LOG_FILE, "a+"){ |f| f.puts
"#{@inbox.Items.Count}: Messages" }
                     begin
                      @inbox.Items.each do |message|

                      File.open(LOG_FILE, "a+"){ |f| f.puts
"====mesage time:#{message.ReceivedTime}" }
                             time_of_the_message =
parsedate(message.ReceivedTime)
                        #this gives us the array containing the time
                             timed_time_of_the_message =
Time.mktime(time_of_the_message[0],time_of_the_message[1],time_of_the_message[2],time_of_the_message[3],time_of_the_message[4],time_of_the_message[5])
                        #we will compare this time with the last time
object and go in for looking
                        #onto attachment if this is newer
                             File.open(LOG_FILE, "a+"){ |f| f.puts
"time difference:#{timed_time_of_the_message-timed_last_time}"}
                                if timed_time_of_the_message >
timed_last_time
                                       message.Attachments.each do |
attachment|


 
filepattern=attachment.fileName.to_s.index(/NBH_|BBH_/)
                                                   if filepattern !=
nil
                                                  File.open(LOG_FILE,
"a+"){ |f| f.puts "======#{attachment.fileName.to_s}"}

                                                   temp_filename = "C:\
\instantrails\\rails_apps\\kpi\\vendor\\service\\temp\
\#{attachment.FileName}"
                                                   Dir.foreach("C:\
\instantrails\\rails_apps\\kpi\\vendor\\service\\temp\\") { |x|
File.delete("C:\\instantrails\\rails_apps\\kpi\\vendor\\service\\temp\
\"+ x) if x!= "." && x!=".." }
 
attachment.SaveAsFile(temp_filename)
                                                   #we will now call
the fileupdater method of kpimumbaicontroller object
 
@a.fileupdateupdater(temp_filename)

                                                   @file_c +=1
                                                   end
                                        end
                                else
                                next
                                end

                       timed_last_time=timed_time_of_the_message
                      end
                      rescue Exception => err
                        File.open(LOG_FILE, "a+"){ |fh| fh.puts 'the
error at inner begin: ' + err }

                         raise

                       end




               msg = 'mailbox spawn succ  at : ' + Time.now.to_s
               File.open(LOG_FILE, "a+"){ |f| f.puts msg }

               rescue Exception => err
                        File.open(LOG_FILE, "a+"){ |fh| fh.puts 'the
error at outer begin: ' + err }
                         #close @sqlconnection
                         raise
                  #msg = 'mail box spawn FAILED  at : ' +
Time.now.to_s
                  #File.open(LOG_FILE, "a+"){ |f| f.puts msg }
               end
       #finally after every spawn we need to update the last time
stamp entry in the spawn file
               File.open("C:\\instantrails\\rails_apps\\kpi\\vendor\
\service\\spawntime.log", "w+"){ |f| f.puts timed_last_time }
               #outlook.close
               sleep 180
            else
               msg = 'non running state entered at : ' +
Time.now.to_s
               File.open(LOG_FILE, "a+"){ |f| f.puts msg }
               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

   svc=Daemon.new
    svc.mainloop

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

   raise
end

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


Sorry for a long code...

The problem is that  my log file loooks like this
============================
kpimumbai_controller.rb required
service_main entered at: Tue Apr 08 17:30:24 +0530 2008
running state entered at : Tue Apr 08 17:30:24 +0530 2008
just before readlines
=====last_time:Mon Oct 04 19:03:24 +0530 1971
=====arr_last_time:197110419324+05301
====timed_last_time:Mon Oct 04 19:03:24 +0530 1971
0:Unread Messages
0: Messages
mailbox spawn succ  at : Tue Apr 08 17:30:24 +0530 2008
===========================================

the inbox messagecount is returning 0 messages.

while if i run it without any service deamon via simple code like this

require 'win32ole'
outlook = WIN32OLE.new('Outlook.Application')
mapi = outlook.GetNameSpace('MAPI')
inbox = mapi.GetDefaultFolder(6)
file_c=1

#methods = []
#arrival_time=inbox.Items(1).ReceivedTime
#b=arrival_time.to_a
#puts arrival_time
#require "parsedate.rb"
#include ParseDate
#formatted_date=parsedate(arrival_time)
#p formatted_date
puts "#{inbox.UnreadItemCount}:so many unread messages"
puts "#{inbox.Items.Count}:so many messages"
=======================

i get output like a champ
===============
484:so many unread messages
11398:so many messages
========================


i am battling it out for last couple of days to find why.
 and i need help badly.


Br

Rajib