lib/ass_launcher/enterprise/ole/ole_binaries.rb
# encoding: utf-8
require 'ass_launcher/enterprise/ole/win32ole'
#
module AssLauncher
class Configuration
# Forcing to use in-process x86_64 1C Ole server in x86_64 Ruby.
attr_writer :use_x86_64_ole
# Forcing to use in-process x86_64 1C Ole server in x86_64 Ruby.
def use_x86_64_ole?
@use_x86_64_ole ||= false
end
end
module Enterprise
#
module Ole
# Wrappers fore 1C Enterprise OLE servers
module OleBinaries
# @abstract
class AbstractAssOleBinary
include AssLauncher::Support::Platforms
# @return [Gem::Version::Requirement]
attr_reader :requirement
# @param requirement [Gem::Version::Requirement] version of 1C Ole
# server
def initialize(requirement)
fail NotImplementedError, 'WIN32OLE undefined for this machine' if\
linux?
@requirement = Gem::Version::Requirement.new(requirement)
end
# @return [WIN32OLE] 1C Ole server object
def ole
@ole ||= new_ole
end
def new_ole
reg
WIN32OLE.new(prog_id)
end
private :new_ole
def v8x
instaled_version.to_s.split('.').slice(0, 2).join('')
end
private :v8x
def instaled_version
return binary_wrapper.version if binary_wrapper
end
alias_method :version, :instaled_version
# @return [AssLauncher::Enterprise::BinaryWrapper]
def binary_wrapper
@binary_wrapper ||= _binary_wrapper
end
protected :binary_wrapper
def _binary_wrapper
fail 'Abstract method call'
end
private :_binary_wrapper
def registred_version
fail NotImplementedError # FIXME: not find object in WinReg
end
private :registred_version
# Return +true+ if 1C Ole object instaled
def instaled?
return false unless version
requirement.satisfied_by?(version) && File.file?(path.to_s)
end
def registred?
# FIXME: always return false and not find object in WinReg
# registred_version == version
false # FIXME
end
private :registred?
# Register Ole server
def reg
return true if registred?
fail "Platform version `#{requirement}' not instaled." unless\
instaled?
reg_server
end
def reg_server
fail 'Abstract method call'
end
private :reg_server
# Unregister Ole server
def unreg
return true unless registred?
fail "Platform version `#{requirement}' not instaled." unless\
instaled?
unreg_server
end
def unreg_server
fail 'Abstract method call'
end
private :unreg_server
def path
@path ||= _path
end
protected :path
def binary
fail 'Abstract method call'
end
protected :binary
def _path
return unless binary_wrapper
platform.path(File.join(binary_wrapper.path.dirname.to_s, binary))
end
private :_path
def clsid
clsids[v8x]
end
protected :clsid
def clsids
fail 'Abstract method call'
end
protected :clsids
end
# Wrapper for v8x.COMConnector in-process OLE server
# @note It work not correct. If old version ole object is loded in
# memory new registred version will be ignored.
class COMConnector < AbstractAssOleBinary
require 'English'
BINARY = 'comcntr.dll'
# Ruby for x32 architectures
X32_ARCHS = ['i386-mingw32', 'i386-cygwin']
# (see AbstractAssOleBinary#initialize)
def initialize(requirement)
super requirement
fail unstable if failure_unstable?
end
def failure_unstable?
ruby_x86_64? && !AssLauncher.config.use_x86_64_ole?
end
def unstable
"v8x.COMConnector is unstable in #{arch} Ruby.\n"\
"Set `AssLauncher.config.use_x86_64_ole' for bypass this failure."
end
private :unstable
def arch
RbConfig::CONFIG['arch']
end
def x32_arch?
X32_ARCHS.include? arch
end
def ruby_x86_64?
!x32_arch?
end
def binary
BINARY
end
private :binary
def prog_id
"v#{v8x}.COMConnector"
end
private :prog_id
def clsids
{ '83' => '{181E893D-73A4-4722-B61D-D604B3D67D47}',
'82' => '{2B0C1632-A199-4350-AA2D-2AEE3D2D573A}',
'81' => '{48EE4DBA-DE11-4af2-83B9-1F7FD6B6B3E3}'
}
end
private :clsids
def _binary_wrapper
Enterprise.thick_clients(requirement.to_s).select do |bw|
bw.x86_64? == ruby_x86_64?
end.sort.last
end
private :_binary_wrapper
# @note It work not correct. If old version ole object is loded in
# memory new registred version will be ignored.
def reg_server
fail_reg_unreg_server('register', reg_unreg_server('i'))
end
private :reg_server
def unreg_server
fail_reg_unreg_server('unregister', reg_unreg_server('u'))
end
private :unreg_server
def reg_unreg_server(mode)
`regsvr32 /#{mode} /s "#{path.win_string}"`
childe_status
end
private :reg_unreg_server
def childe_status
$CHILD_STATUS
end
private :childe_status
def fail_reg_unreg_server(message, status)
fail "Failure #{message} `#{path.win_string}' #{status}" unless\
status.success?
status
end
private :fail_reg_unreg_server
end
# Wrapper for v8x.Application standalone OLE server
class ThickApplication < AbstractAssOleBinary
BINARY = '1cv8.exe'
def binary
BINARY
end
private :binary
def prog_id
"v#{v8x}.Application"
end
private :prog_id
def _binary_wrapper
Enterprise.thick_clients(requirement.to_s).sort.last
end
private :_binary_wrapper
def reg_server
run_as_enterprise reg_server_args
end
private :reg_server
def reg_server_args
r = ['/regserver']
r << '-currentuser' if version >= Gem::Version.new('8.3.9')
r
end
private :reg_server_args
def unreg_server
run_as_enterprise ['/unregserver']
end
private :unreg_server
def run_as_enterprise(args)
binary_wrapper.command(:enterprise, args)
.run.wait.result.verify!
end
private :run_as_enterprise
end
# Wrapper for v8xc.Application standalone OLE server
class ThinApplication < ThickApplication
BINARY = '1cv8c.exe'
def binary
BINARY
end
private :binary
def prog_id
"v#{v8x}c.Application"
end
private :prog_id
def _binary_wrapper
Enterprise.thin_clients(requirement.to_s).sort.last
end
private :_binary_wrapper
def run_as_enterprise(args)
binary_wrapper.command(args)
.run.wait.result.verify!
end
private :run_as_enterprise
end
end
end
end
end