[英]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.