1

When i am using win32ole as stand alone application at that time everything seems working fine, as soon as i put into my rails application which is running on mongrel server it goes into infinite loop.

I am trying to access "https://microsoft/sharepoint/document.doc"

def generatertm(issue) 
begin 
  word = WIN32OLE.new('word.application') 
  logger.debug("Word Initialized...") 
  word.visible = true 
  myDocLink = "https://microsoft/sharepoint/url.doc" 
  myFile = word.documents.open(myDocLink) 
  logger.debug("File Opened...") 
  puts "Started Reading bookmarks..." 
  myBookMarks = myFile.Bookmarks puts "bookmarks fetched working background task..."

  print ("Bookmakr Count : " + myBookMarks.Count.to_s + "\n")

  myBookMarks.each do |i|
    logger.warn ("Bookmark Name : " + i.Name + "\n")
  end
rescue WIN32OLERuntimeError => e
  puts e.message
  puts e.backtrace.inspect
  else
ensure

word.activedocument.close( true )  # presents save dialog box
#word.activedocument.close(false) # no save dialog, just close it
word.quit
end
end

When i run this code stand alone at that time one Pop up come for Microsoft Share point credentials. however in mongrel rails it goes into infinite loop.

Do i need to handle this pop up to appear through Rails?

  • Progress - When i went into "Services" in Windows environment - In Mongrel Service Properties there is one option in "Log On -> Allow to interact with Desktop" When i checked it and tried to run my code i got "Interactive Services Detection - A program running on this computer is trying to display a message [Content] The program might need information form you or your permission to complete a task. Why does this happen? [V] Show program details [View the message] [Ask me later]" So how to get this service prompt at browser and not in background? Am i going into the right direction? – Bhavin Shah May 02 '12 at 12:07

1 Answers1

0

Have you looked into patching the win32ole.rb file?

Basically, here's the reason for the patch:

t turns out that win32ole.rb patches the thread to call the windows OleInitialize() & OleUninitialize() functions around the yield to the block. However, the MS documentation for CoInitialize (which OleInitialize calls internally) state that: "the first thread in the application that calls CoInitialize with 0 (or CoInitializeEx with COINIT_APARTMENTTHREADED) must be the last thread to call CoUninitialize. Otherwise, subsequent calls to CoInitialize on the STA will fail and the application will not work." http://msdn.microsoft.com/en-us/library/ms678543(v=VS.85).aspx

And here's the modified win32ole.rb file to fix the threading issue:

require 'win32ole.so'

# Fail if not required by main thread.
# Call OleInitialize and OleUninitialize for main thread to satisfy the following:
#
# The first thread in the application that calls CoInitialize with 0 (or CoInitializeEx with COINIT_APARTMENTTHREADED)
# must be the last thread to call CoUninitialize. Otherwise, subsequent calls to CoInitialize on the STA will fail and the
# application will not work.
#
# See http://msdn.microsoft.com/en-us/library/ms678543(v=VS.85).aspx
if Thread.main != Thread.current
  raise "Require win32ole.rb from the main application thread to satisfy CoInitialize requirements."
else
  WIN32OLE.ole_initialize
  at_exit { WIN32OLE.ole_uninitialize }
end


# re-define Thread#initialize
# bug #2618(ruby-core:27634)

class Thread
  alias :org_initialize :initialize
  def initialize(*arg, &block)
    if block
      org_initialize(*arg) {
        WIN32OLE.ole_initialize
        begin
          block.call(*arg)
        ensure
          WIN32OLE.ole_uninitialize
        end
      }
    else
      org_initialize(*arg)
    end
  end
end

http://cowlibob.co.uk/ruby-threads-win32ole-coinitialize-and-counin

Dominic Tancredi
  • 41,134
  • 7
  • 34
  • 50
  • Yes i have seen this before however did not understood the context just now when i went into the services i understood it. So you mean i have to manage the thread using this code. And have to put ONLY this fix on win32ole.rb and use it? – Bhavin Shah May 02 '12 at 12:30
  • I am using redmine. I have created win32ole.rb and put this code in it. I have put this file in initializer folder. I have restarted the Mongrel Services, However when i have tried access the server localhost:3000 it is not responding. Do i need to remove those log on settings in from the service? – Bhavin Shah May 02 '12 at 12:47
  • I have debugged it in my mongrel log "/config/initializers/win32ole.rb:12: undefined method `ole_initialize' for WIN32OLE:Class (NoMethodError)" and when i further digged into it i have found out that the ruby version[1.8.7] which i am using does not have win32ole.rb file in source itself. i.e. http://rxr.whitequark.org/mri/source/ext/win32ole/lib/win32ole.rb?v=1.8.7 – Bhavin Shah May 02 '12 at 13:52
  • Whoa, you're using 1.8.7? I thought the version was higher. Can you upgrade to 1.9.1 / 1.9.2 / 1.9.2? It wouldn't "include" if it didn't exist. – Dominic Tancredi May 02 '12 at 17:01
  • Yes i have upgraded it to 1.9.3. However no progress same error. Got Following error : - "Unhandled listen loop exception #. user/path/redmine/config/initializers/win32ole.rb:19 ** INT signal received." <<< if block>>> .... apart from this when i start mongrel service it shows me that ""Interactive Services Detection" is it something related to Mongrel Service which i have installed is not support on Windows 7 Ultmiate? – Bhavin Shah May 04 '12 at 07:03