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

KERNEL32 =
Fiddle.dlopen('kernel32.dll')

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(path) ⇒ DllDirectory

See RubyInstaller::Build.add_dll_directory



44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
# File 'lib/ruby_installer/build/dll_directory.rb', line 44

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

  if @@add_dll_dir_available
    # 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.



31
32
33
# File 'lib/ruby_installer/build/dll_directory.rb', line 31

def path
  @path
end

Class Method Details

.add_dll_directory_winapi(path) ⇒ Object

Raises:



78
79
80
81
82
83
84
85
# File 'lib/ruby_installer/build/dll_directory.rb', line 78

def self.add_dll_directory_winapi(path)
  strutf16 = (path + "\0").encode(Encoding::UTF_16LE)
  strptr = Fiddle::Pointer.malloc(strutf16.bytesize)
  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:



74
75
76
# File 'lib/ruby_installer/build/dll_directory.rb', line 74

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.



37
38
39
40
41
# File 'lib/ruby_installer/build/dll_directory.rb', line 37

def self.set_defaults
  if @@add_dll_dir_available
    set_default_dll_directories_winapi
  end
end

Instance Method Details

#removeObject

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



88
89
90
91
92
93
94
# File 'lib/ruby_installer/build/dll_directory.rb', line 88

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