Class: RubyInstaller::Build::DllDirectory

Inherits:
Object
  • Object
show all
Defined in:
lib/ruby_installer/build/dll_directory.rb

Overview

:nodoc:

Defined Under Namespace

Classes: Error, WinApiError

Constant Summary collapse

@@dll_directory_mechanism =
:path

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ DllDirectory

See RubyInstaller::Build.add_dll_directory



58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/ruby_installer/build/dll_directory.rb', line 58

def initialize(path)
  path = File.expand_path(path)

  if @@dll_directory_mechanism != :path
    # Prefer Winapi function AddDllDirectory(), which requires Windows 7 with KB2533623 or newer.
    self.class.set_default_dll_directories_winapi
    @handle = self.class.add_dll_directory_winapi(path)
    @path = path
  else
    raise Error, "invalid path #{path}" unless File.directory?(path)
    # For older systems fall back to the legacy method of using PATH environment variable.
    if ENV['PATH'].include?(path)
      @handle = nil
      @path = nil
    else
      $stderr.puts "Temporarily enhancing PATH by #{path}..." if $DEBUG
      ENV['PATH'] = path + ";" + ENV['PATH']
      @handle = nil
      @path = path
    end
  end
  return unless block_given?
  begin
    yield self
  ensure
    remove
  end
end

Instance Attribute Details

#pathObject (readonly)

Returns the value of attribute path.



45
46
47
# File 'lib/ruby_installer/build/dll_directory.rb', line 45

def path
  @path
end

Class Method Details

.add_dll_directory_winapi(path) ⇒ Object

Raises:



93
94
95
96
97
98
99
100
# File 'lib/ruby_installer/build/dll_directory.rb', line 93

def self.add_dll_directory_winapi(path)
  strutf16 = (path + "\0").encode(Encoding::UTF_16LE)
  strptr = Fiddle::Pointer.malloc(strutf16.bytesize, Fiddle::RUBY_FREE)
  strptr[0, strptr.size] = strutf16
  handle = AddDllDirectory.call(strptr)
  raise WinApiError, "AddDllDirectory failed for #{path}" if handle.null?
  handle
end

.set_default_dll_directories_winapiObject

Set default search paths to LOAD_LIBRARY_SEARCH_DEFAULT_DIRS to include path added by add_dll_directory_winapi() and exclude paths set per PATH environment variable.

Raises:



88
89
90
# File 'lib/ruby_installer/build/dll_directory.rb', line 88

def self.set_default_dll_directories_winapi
  raise WinApiError, "SetDefaultDllDirectories failed" if SetDefaultDllDirectories.call(0x00001000)==0
end

.set_defaultsObject

Set default search paths to the application directory (where ruby.exe resides) and to paths that are added per DllDirectory.new(). It disables the PATH environment variable for DLL search.

This method is usually called while RubyInstaller startup.



51
52
53
54
55
# File 'lib/ruby_installer/build/dll_directory.rb', line 51

def self.set_defaults
  if @@dll_directory_mechanism != :path
    set_default_dll_directories_winapi
  end
end

Instance Method Details

#removeObject

This method removes the given directory from the active DLL search paths.



110
111
112
113
114
115
116
# File 'lib/ruby_installer/build/dll_directory.rb', line 110

def remove
  if @handle
    raise WinApiError, "RemoveDllDirectory failed for #{@path}" if RemoveDllDirectory.call(@handle) == 0
  elsif @path
    ENV['PATH'] = ENV['PATH'].sub(@path + ";", "")
  end
end