win32/registry is registry accessor library for Win32 platform. It uses dl/import to call Win32 Registry APIs.
Win32::Registry::HKEY_CURRENT_USER.open('SOFTWARE\foo') do |reg| value = reg['foo'] # read a value value = reg['foo', Win32::Registry::REG_SZ] # read a value with type type, value = reg.read('foo') # read a value reg['foo'] = 'bar' # write a value reg['foo', Win32::Registry::REG_SZ] = 'bar' # write a value with type reg.write('foo', Win32::Registry::REG_SZ, 'bar') # write a value reg.each_value { |name, type, data| ... } # Enumerate values reg.each_key { |key, wtime| ... } # Enumerate subkeys reg.delete_value(name) # Delete a value reg.delete_key(name) # Delete a subkey reg.delete_key(name, true) # Delete a subkey recursively end
— info
— num_keys
— max_key_length
— num_values
— max_value_name_length
— max_value_length
— descriptor_length
— wtime
Returns an item of key information.
— HKEY_CLASSES_ROOT
— HKEY_CURRENT_USER
— HKEY_LOCAL_MACHINE
— HKEY_PERFORMANCE_DATA
— HKEY_CURRENT_CONFIG
— HKEY_DYN_DATA
Win32::Registry object whose key is predefined key.
For detail, see the MSDN article.
— Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)
— Registry.create(key, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) { |reg| … }
Create or open the registry key subkey under key. You can use predefined key HKEY_* (see Constants)
If subkey is already exists, key is opened and Registry#created? method will return false.
If block is given, the key is closed automatically.
# File dl/win32/lib/win32/registry.rb, line 411
def self.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED)
newkey, disp = API.CreateKey(hkey.hkey, subkey, opt, desired)
obj = new(newkey, hkey, subkey, disp)
if block_given?
begin
yield obj
ensure
obj.close
end
else
obj
end
end
Replace %w+% into the environment value of what is contained between the %‘s This method is used for REG_EXPAND_SZ.
For detail, see expandEnvironmentStrings Win32 API.
# File dl/win32/lib/win32/registry.rb, line 332
def self.expand_environ(str)
str.gsub(/%([^%]+)%/) { ENV[$1] || ENV[$1.upcase] || $& }
end
initialize
# File dl/win32/lib/win32/registry.rb, line 433
def initialize(hkey, parent, keyname, disposition)
@hkey = hkey
@parent = parent
@keyname = keyname
@disposition = disposition
@hkeyfinal = [ hkey ]
ObjectSpace.define_finalizer self, @@final.call(@hkeyfinal)
end
— Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)
— Registry.open(key, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) { |reg| … }
Open the registry key subkey under key. key is Win32::Registry object of parent key. You can use predefined key HKEY_* (see Constants) desired and opt is access mask and key option. For detail, see the MSDN. If block is given, the key is closed automatically.
# File dl/win32/lib/win32/registry.rb, line 383
def self.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED)
subkey = subkey.chomp('\')
newkey = API.OpenKey(hkey.hkey, subkey, opt, desired)
obj = new(newkey, hkey, subkey, REG_OPENED_EXISTING_KEY)
if block_given?
begin
yield obj
ensure
obj.close
end
else
obj
end
end
Convert Time object or Integer object into 64-bit FILETIME.
# File dl/win32/lib/win32/registry.rb, line 363
def self.time2wtime(time)
time.to_i * 10000000 + 116444736000000000
end
Read a registry value named name and return its value data. The class of value is same as read method returns.
If the value type is REG_EXPAND_SZ, returns value data whose environment variables are replaced. If the value type is neither REG_SZ, REG_MULTI_SZ, REG_DWORD, REG_DWORD_BIG_ENDIAN, nor REG_QWORD, TypeError is raised.
The meaning of rtype is same as read method.
# File dl/win32/lib/win32/registry.rb, line 620
def [](name, *rtype)
type, data = read(name, *rtype)
case type
when REG_SZ, REG_DWORD, REG_QWORD, REG_MULTI_SZ
data
when REG_EXPAND_SZ
Registry.expand_environ(data)
else
raise TypeError, "Type #{type} is not supported."
end
end
Write value to a registry value named name.
If wtype is specified, the value type is it. Otherwise, the value type is depend on class of value: :Integer
REG_DWORD
:String
REG_SZ
:Array
REG_MULTI_SZ
# File dl/win32/lib/win32/registry.rb, line 715
def []=(name, rtype, value = nil)
if value
write name, rtype, value
else
case value = rtype
when Integer
write name, REG_DWORD, value
when String
write name, REG_SZ, value
when Array
write name, REG_MULTI_SZ, value
else
raise TypeError, "Unexpected type #{value.class}"
end
end
value
end
marshalling is not allowed
# File dl/win32/lib/win32/registry.rb, line 488
def _dump(depth)
raise TypeError, "can't dump Win32::Registry"
end
Close key.
After close, most method raise an error.
# File dl/win32/lib/win32/registry.rb, line 511
def close
API.CloseKey(@hkey)
@hkey = @parent = @keyname = nil
@hkeyfinal[0] = nil
end
Same as Win32::Registry.create (self, subkey, desired, opt)
# File dl/win32/lib/win32/registry.rb, line 502
def create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk)
self.class.create(self, subkey, desired, opt, &blk)
end
Returns if key is created ((newly)). (see Registry.create) – basically you call create then when you call created? on the instance returned it will tell if it was successful or not
# File dl/win32/lib/win32/registry.rb, line 458
def created?
@disposition == REG_CREATED_NEW_KEY
end
Delete a subkey named name and all its values.
If recursive is false, the subkey must not have subkeys. Otherwise, this method deletes all subkeys and values recursively.
# File dl/win32/lib/win32/registry.rb, line 778
def delete_key(name, recursive = false)
if recursive
open(name, KEY_ALL_ACCESS) do |reg|
reg.keys.each do |key|
begin
reg.delete_key(key, true)
rescue Error
#
end
end
end
API.DeleteKey(@hkey, name)
else
begin
API.EnumKey @hkey, 0
rescue Error
return API.DeleteKey(@hkey, name)
end
raise Error.new(5) ## ERROR_ACCESS_DENIED
end
end
Delete a registry value named name. We can not delete the `default’ value.
# File dl/win32/lib/win32/registry.rb, line 767
def delete_value(name)
API.DeleteValue(@hkey, name)
end
Enumerate subkeys.
subkey is String which contains name of subkey. wtime is last write time as FILETIME (64-bit integer). (see Registry.wtime2time)
# File dl/win32/lib/win32/registry.rb, line 547
def each_key
index = 0
while true
begin
subkey, wtime = API.EnumKey(@hkey, index)
rescue Error
break
end
yield subkey, wtime
index += 1
end
index
end
Enumerate values.
# File dl/win32/lib/win32/registry.rb, line 520
def each_value
index = 0
while true
begin
subkey = API.EnumValue(@hkey, index)
rescue Error
break
end
begin
type, data = read(subkey)
rescue Error
next
end
yield subkey, type, data
index += 1
end
index
end
Write all the attributes into the registry file.
# File dl/win32/lib/win32/registry.rb, line 803
def flush
API.FlushKey @hkey
end
Returns key information as Array of: :num_keys
The number of subkeys.
:max_key_length
Maximum length of name of subkeys.
:num_values
The number of values.
:max_value_name_length
Maximum length of name of values.
:max_value_length
Maximum length of value of values.
:descriptor_length
Length of security descriptor.
:wtime
Last write time as FILETIME(64-bit integer)
For detail, see RegQueryInfoKey Win32 API.
# File dl/win32/lib/win32/registry.rb, line 826
def info
API.QueryInfoKey(@hkey)
end
# File dl/win32/lib/win32/registry.rb, line 481
def inspect
"\#<Win32::Registry key=#{name.inspect}>"
end
return keys as an array
# File dl/win32/lib/win32/registry.rb, line 564
def keys
keys_ary = []
each_key { |key,| keys_ary << key }
keys_ary
end
Full path of key such as ‘HKEY_CURRENT_USERSOFTWAREfoobar’.
# File dl/win32/lib/win32/registry.rb, line 472
def name
parent = self
name = @keyname
while parent = parent.parent
name = parent.keyname + '\' + name
end
name
end
Same as Win32::Registry.open (self, subkey, desired, opt)
# File dl/win32/lib/win32/registry.rb, line 495
def open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk)
self.class.open(self, subkey, desired, opt, &blk)
end
Returns if key is not closed.
# File dl/win32/lib/win32/registry.rb, line 465
def open?
!@hkey.nil?
end
Read a registry value named name and return array of [ type, data ]. When name is nil, the `default’ value is read. type is value type. (see Win32::Registry::Constants module) data is value data, its class is: :REG_SZ, REG_EXPAND_SZ
String
:REG_MULTI_SZ
Array of String
:REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD
Integer
:REG_BINARY
String (contains binary data)
When rtype is specified, the value type must be included by rtype array, or TypeError is raised.
# File dl/win32/lib/win32/registry.rb, line 586
def read(name, *rtype)
type, data = API.QueryValue(@hkey, name)
unless rtype.empty? or rtype.include?(type)
raise TypeError, "Type mismatch (expect #{rtype.inspect} but #{type} present)"
end
case type
when REG_SZ, REG_EXPAND_SZ
[ type, data.chop ]
when REG_MULTI_SZ
[ type, data.split(/\00//) ]
when REG_BINARY
[ type, data ]
when REG_DWORD
[ type, API.unpackdw(data) ]
when REG_DWORD_BIG_ENDIAN
[ type, data.unpack('N')[0] ]
when REG_QWORD
[ type, API.unpackqw(data) ]
else
raise TypeError, "Type #{type} is not supported."
end
end
Read a REG_SZ or REG_EXPAND_SZ registry value named name.
If the value type is REG_EXPAND_SZ, environment variables are replaced. Unless the value type is REG_SZ or REG_EXPAND_SZ, TypeError is raised.
# File dl/win32/lib/win32/registry.rb, line 646
def read_s_expand(name)
type, data = read(name, REG_SZ, REG_EXPAND_SZ)
if type == REG_EXPAND_SZ
Registry.expand_environ(data)
else
data
end
end
Write data to a registry value named name. When name is nil, write to the `default’ value.
type is type value. (see Registry::Constants module) Class of data must be same as which read method returns.
# File dl/win32/lib/win32/registry.rb, line 683
def write(name, type, data)
case type
when REG_SZ, REG_EXPAND_SZ
data = data.to_s + "\00""
when REG_MULTI_SZ
data = data.to_a.join("\00"") + "\00\\00""
when REG_BINARY
data = data.to_s
when REG_DWORD
data = API.packdw(data.to_i)
when REG_DWORD_BIG_ENDIAN
data = [data.to_i].pack('N')
when REG_QWORD
data = API.packqw(data.to_i)
else
raise TypeError, "Unsupported type #{type}"
end
API.SetValue(@hkey, name, type, data, data.length)
end