简体   繁体   English

在Ruby上使用WIN32OLE从Remote Server渲染Word文档

[英]Render Word Document from Remote Server using WIN32OLE in ruby on rails

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. 当我当时使用win32ole作为独立应用程序时,一切似乎都正常运行,一旦我将其放入运行在mongrel服务器上的rails应用程序中,就会陷入无限循环。

I am trying to access "https://microsoft/sharepoint/document.doc" 我正在尝试访问“ 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. 当我当时单独运行此代码时,将弹出一个弹出窗口,以获取Microsoft共享点凭据。 however in mongrel rails it goes into infinite loop. 但是在杂种轨道中,它会陷入无限循环。

Do i need to handle this pop up to appear through Rails? 我是否需要处理此弹出窗口才能通过Rails出现?

Have you looked into patching the win32ole.rb file? 您是否研究过修补win32ole.rb文件?

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. 事实证明,win32ole.rb修补了线程,以围绕该块的收益率调用Windows OleInitialize()和OleUninitialize()函数。 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." 但是,CoInitialize的MS文档(OleInitialize在内部对其进行调用)指出:“应用程序中调用CoInitialize的值为0(或CoInitializeEx的值为COINIT_APARTMENTTHREADED)的第一个线程必须是调用CoUninitialize的最后一个线程。否则,后续对CoInitialize的调用STA将失败,应用程序将无法运行。” http://msdn.microsoft.com/en-us/library/ms678543(v=VS.85).aspx http://msdn.microsoft.com/zh-CN/library/ms678543(v=VS.85).aspx

And here's the modified win32ole.rb file to fix the threading issue: 这是修改后的win32ole.rb文件,用于解决线程问题:

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 http://cowlibob.co.uk/ruby-threads-win32ole-coinitialize-and-counin

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM