Module: Wine

Defined in:
documented/wine.rb

Overview

Namespace for Wine runtime registry access and configuration.

Provides methods to read and write Windows registry values through a Wine prefix when Wine is detected on the system. Only defined if Wine is available and both BIN and PREFIX point to valid executable and directory paths.

Constant Summary collapse

BIN =

[String] Absolute path to the Wine executable.

Resolved from --wine= CLI override, PATH lookup, or nil if Wine is not available or explicitly disabled with --no-wine.

$wine_bin
PREFIX =

[String] Absolute path to the Wine prefix (WINEPREFIX directory).

Resolved from --wine-prefix= CLI override, WINEPREFIX environment variable, or $HOME/.wine by default. Only set when BIN points to a valid Wine executable and this directory exists.

$wine_prefix

Class Method Summary collapse

Class Method Details

.registry_gets(key) ⇒ String, false

Reads a value from Wine's system.reg for HKEY_LOCAL_MACHINE keys.

Note: malformed keys now intentionally raise ArgumentError (instead of the previous incidental NoMethodError from calling captures on nil).

Parameters:

  • key (String) —

    registry path, e.g. HKEY_LOCAL_MACHINE\Software\Foo\Bar

Returns:

  • (String, false) —

    value string when found, false otherwise

Raises:

  • (ArgumentError) —

    when key is not a supported registry path format



79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
# File 'documented/wine.rb', line 79

def self.registry_gets(key)
  match_data = /(HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER)\\(.+)\\([^\\]*)/.match(key)
  raise ArgumentError, "Invalid registry key format: #{key.inspect}" unless match_data

  hkey, subkey, thingie = match_data.captures # fixme: stupid highlights ]/
  if File.exist?(PREFIX + '/system.reg')
    if hkey == 'HKEY_LOCAL_MACHINE'
      subkey = "[#{subkey.gsub('\\', '\\\\\\')}]"
      if thingie.nil? or thingie.empty?
        thingie = '@'
      else
        thingie = "\"#{thingie}\""
      end
      lookin = result = false
      File.open(PREFIX + '/system.reg') { |f| f.readlines }.each { |line|
        if line[0...subkey.length].casecmp?(subkey)
          lookin = true
        elsif line =~ /^\[/
          lookin = false
        elsif lookin
          value_match = /^#{thingie}="(.*)"$/i.match(line)
          next unless value_match

          result = value_match[1].split('\\"').join('"').split('\\\\').join('\\').sub(/\\0$/, '')
          break
        end
      }
      return result
    else
      return false
    end
  else
    return false
  end
end

.registry_puts(key, value) ⇒ Boolean

Writes a registry value through regedit using a temporary .reg file. Uses argv-style system invocation to avoid shell interpolation.

Note: malformed keys now intentionally raise ArgumentError (instead of the previous incidental NoMethodError from calling captures on nil).

Parameters:

  • key (String) —

    registry path, e.g. HKEY_LOCAL_MACHINE\Software\Foo\Bar

  • value (String) —

    value to persist

Returns:

  • (Boolean) —

    true on successful write path, false on failures or regedit non-zero exit

Raises:

  • (ArgumentError) —

    when key is not a supported registry path format



124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
# File 'documented/wine.rb', line 124

def self.registry_puts(key, value)
  match_data = /(HKEY_LOCAL_MACHINE|HKEY_CURRENT_USER)\\(.+)\\([^\\]*)/.match(key)
  raise ArgumentError, "Invalid registry key format: #{key.inspect}" unless match_data

  hkey, subkey, thingie = match_data.captures # fixme ]/
  if File.exist?(PREFIX)
    if thingie.nil? or thingie.empty?
      thingie = '@'
    else
      thingie = "\"#{thingie}\""
    end
    # gsub sucks for this..
    value = value.split('\\').join('\\\\')
    value = value.split('"').join('\"')
    filename = nil
    begin
      regedit_data = "REGEDIT4\n\n[#{hkey}\\#{subkey}]\n#{thingie}=\"#{value}\"\n\n"
      filename = "#{TEMP_DIR}/wine-#{Time.now.to_i}.reg"
      File.open(filename, 'w') { |f| f.write(regedit_data) }
      succeeded = system(BIN, 'regedit', filename)
      return false unless succeeded
      sleep 0.2
    rescue StandardError
      return false
    ensure
      File.delete(filename) if filename && File.exist?(filename)
    end
    return true
  end
  false
end