Class: Win32::Registry

Inherits:
Object
  • Object
show all
Includes:
Enumerable, Constants
Defined in:
win32/lib/win32/registry.rb

Overview

Win32 Registry

win32/registry is registry accessor library for Win32 platform. It uses fiddle/import to call Win32 Registry APIs.

example

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

Reference

Win32::Registry class

— info

— num_keys

— max_key_length

— num_values

— max_value_name_length

— max_value_length

— descriptor_length

— wtime

Returns an item of key information.

constants

— 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.

Direct Known Subclasses

PredefinedKey

Defined Under Namespace

Modules: API, Constants Classes: Error, PredefinedKey

Constant Summary collapse

@@type2name =
{ }
@@final =

finalizer

proc { |hkey| proc { API.CloseKey(hkey[0]) if hkey[0] } }

Constants included from Constants

Constants::HKEY_CLASSES_ROOT, Constants::HKEY_CURRENT_CONFIG, Constants::HKEY_CURRENT_USER, Constants::HKEY_DYN_DATA, Constants::HKEY_LOCAL_MACHINE, Constants::HKEY_PERFORMANCE_DATA, Constants::HKEY_PERFORMANCE_NLSTEXT, Constants::HKEY_PERFORMANCE_TEXT, Constants::HKEY_USERS, Constants::KEY_ALL_ACCESS, Constants::KEY_CREATE_LINK, Constants::KEY_CREATE_SUB_KEY, Constants::KEY_ENUMERATE_SUB_KEYS, Constants::KEY_EXECUTE, Constants::KEY_NOTIFY, Constants::KEY_QUERY_VALUE, Constants::KEY_READ, Constants::KEY_SET_VALUE, Constants::KEY_WRITE, Constants::MAX_KEY_LENGTH, Constants::MAX_VALUE_LENGTH, Constants::REG_BINARY, Constants::REG_CREATED_NEW_KEY, Constants::REG_DWORD, Constants::REG_DWORD_BIG_ENDIAN, Constants::REG_DWORD_LITTLE_ENDIAN, Constants::REG_EXPAND_SZ, Constants::REG_FORCE_RESTORE, Constants::REG_FULL_RESOURCE_DESCRIPTOR, Constants::REG_LEGAL_OPTION, Constants::REG_LINK, Constants::REG_MULTI_SZ, Constants::REG_NONE, Constants::REG_NO_LAZY_FLUSH, Constants::REG_OPENED_EXISTING_KEY, Constants::REG_OPTION_BACKUP_RESTORE, Constants::REG_OPTION_CREATE_LINK, Constants::REG_OPTION_NON_VOLATILE, Constants::REG_OPTION_OPEN_LINK, Constants::REG_OPTION_RESERVED, Constants::REG_OPTION_VOLATILE, Constants::REG_QWORD, Constants::REG_QWORD_LITTLE_ENDIAN, Constants::REG_REFRESH_HIVE, Constants::REG_RESOURCE_LIST, Constants::REG_RESOURCE_REQUIREMENTS_LIST, Constants::REG_SZ, Constants::REG_WHOLE_HIVE_VOLATILE, Constants::STANDARD_RIGHTS_READ, Constants::STANDARD_RIGHTS_WRITE

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(hkey, parent, keyname, disposition) ⇒ Registry

initialize



433
434
435
436
437
438
439
440
# File '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

Instance Attribute Details

#dispositionObject (readonly)

Disposition value (REG_CREATED_NEW_KEY or REG_OPENED_EXISTING_KEY).



450
451
452
# File 'win32/lib/win32/registry.rb', line 450

def disposition
  @disposition
end

#hkeyObject (readonly)

Returns key handle value.



443
444
445
# File 'win32/lib/win32/registry.rb', line 443

def hkey
  @hkey
end

#keynameObject (readonly)

Same as subkey value of Registry.open or Registry.create method.



448
449
450
# File 'win32/lib/win32/registry.rb', line 448

def keyname
  @keyname
end

#parentObject (readonly)

Win32::Registry object of parent key, or nil if predefeined key.



445
446
447
# File 'win32/lib/win32/registry.rb', line 445

def parent
  @parent
end

Class Method Details

.create(hkey, subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED) ⇒ Object

— 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.



411
412
413
414
415
416
417
418
419
420
421
422
423
# File '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

.expand_environ(str) ⇒ Object

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.



332
333
334
# File 'win32/lib/win32/registry.rb', line 332

def self.expand_environ(str)
  str.gsub(/%([^%]+)%/) { ENV[$1] || ENV[$1.upcase] || $& }
end

.open(hkey, subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED) ⇒ Object

— 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.



383
384
385
386
387
388
389
390
391
392
393
394
395
396
# File '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

.time2wtime(time) ⇒ Object

Convert Time object or Integer object into 64-bit FILETIME.



363
364
365
# File 'win32/lib/win32/registry.rb', line 363

def self.time2wtime(time)
  time.to_i * 10000000 + 116444736000000000
end

.type2name(type) ⇒ Object

Convert registry type value to readable string.



349
350
351
# File 'win32/lib/win32/registry.rb', line 349

def self.type2name(type)
  @@type2name[type] || type.to_s
end

.wtime2time(wtime) ⇒ Object

Convert 64-bit FILETIME integer into Time object.



356
357
358
# File 'win32/lib/win32/registry.rb', line 356

def self.wtime2time(wtime)
  Time.at((wtime - 116444736000000000) / 10000000)
end

Instance Method Details

#[](name, *rtype) ⇒ Object

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.



620
621
622
623
624
625
626
627
628
629
630
# File '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

#[]=(name, rtype, value = nil) ⇒ Object

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


715
716
717
718
719
720
721
722
723
724
725
726
727
728
729
730
731
# File '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

#_dump(depth) ⇒ Object

marshalling is not allowed

Raises:

  • (TypeError)


488
489
490
# File 'win32/lib/win32/registry.rb', line 488

def _dump(depth)
  raise TypeError, "can't dump Win32::Registry"
end

#closeObject

Close key.

After close, most method raise an error.



511
512
513
514
515
# File 'win32/lib/win32/registry.rb', line 511

def close
  API.CloseKey(@hkey)
  @hkey = @parent = @keyname = nil
  @hkeyfinal[0] = nil
end

#create(subkey, desired = KEY_ALL_ACCESS, opt = REG_OPTION_RESERVED, &blk) ⇒ Object

Same as Win32::Registry.create (self, subkey, desired, opt)



502
503
504
# File '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

#created?Boolean

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

Returns:

  • (Boolean)


458
459
460
# File 'win32/lib/win32/registry.rb', line 458

def created?
  @disposition == REG_CREATED_NEW_KEY
end

#delete_key(name, recursive = false) ⇒ Object

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.



778
779
780
781
782
783
784
785
786
787
788
789
790
791
792
793
794
795
796
797
798
# File '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_value(name) ⇒ Object Also known as: delete

Delete a registry value named name. We can not delete the ‘default’ value.



767
768
769
# File 'win32/lib/win32/registry.rb', line 767

def delete_value(name)
  API.DeleteValue(@hkey, name)
end

#each_keyObject

Enumerate subkeys.

subkey is String which contains name of subkey. wtime is last write time as FILETIME (64-bit integer). (see Registry.wtime2time)



547
548
549
550
551
552
553
554
555
556
557
558
559
# File '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

#each_valueObject Also known as: each

Enumerate values.



520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
# File '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

#flushObject

Write all the attributes into the registry file.



803
804
805
# File 'win32/lib/win32/registry.rb', line 803

def flush
  API.FlushKey @hkey
end

#infoObject

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.



826
827
828
# File 'win32/lib/win32/registry.rb', line 826

def info
  API.QueryInfoKey(@hkey)
end

#inspectObject



481
482
483
# File 'win32/lib/win32/registry.rb', line 481

def inspect
  "\#<Win32::Registry key=#{name.inspect}>"
end

#keysObject

return keys as an array



564
565
566
567
568
# File 'win32/lib/win32/registry.rb', line 564

def keys
  keys_ary = []
  each_key { |key,| keys_ary << key }
  keys_ary
end

#nameObject

Full path of key such as ‘HKEY_CURRENT_USERSOFTWAREfoobar’.



472
473
474
475
476
477
478
479
# File 'win32/lib/win32/registry.rb', line 472

def name
  parent = self
  name = @keyname
  while parent = parent.parent
    name = parent.keyname + '\\' + name
  end
  name
end

#open(subkey, desired = KEY_READ, opt = REG_OPTION_RESERVED, &blk) ⇒ Object

Same as Win32::Registry.open (self, subkey, desired, opt)



495
496
497
# File '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

#open?Boolean

Returns if key is not closed.

Returns:

  • (Boolean)


465
466
467
# File 'win32/lib/win32/registry.rb', line 465

def open?
  !@hkey.nil?
end

#read(name, *rtype) ⇒ Object

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.



586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
# File '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(/\0/) ]
  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_bin(name) ⇒ Object

Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin) registry value named name.

If the values type does not match, TypeError is raised.



671
672
673
# File 'win32/lib/win32/registry.rb', line 671

def read_bin(name)
  read(name, REG_BINARY)[1]
end

#read_i(name) ⇒ Object

Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin) registry value named name.

If the values type does not match, TypeError is raised.



661
662
663
# File 'win32/lib/win32/registry.rb', line 661

def read_i(name)
  read(name, REG_DWORD, REG_DWORD_BIG_ENDIAN, REG_QWORD)[1]
end

#read_s(name) ⇒ Object

Read a REG_SZ(read_s), REG_DWORD(read_i), or REG_BINARY(read_bin) registry value named name.

If the values type does not match, TypeError is raised.



636
637
638
# File 'win32/lib/win32/registry.rb', line 636

def read_s(name)
  read(name, REG_SZ)[1]
end

#read_s_expand(name) ⇒ Object

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.



646
647
648
649
650
651
652
653
# File '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(name, type, data) ⇒ Object

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.



683
684
685
686
687
688
689
690
691
692
693
694
695
696
697
698
699
700
701
# File 'win32/lib/win32/registry.rb', line 683

def write(name, type, data)
  case type
  when REG_SZ, REG_EXPAND_SZ
    data = data.to_s + "\0"
  when REG_MULTI_SZ
    data = data.to_a.join("\0") + "\0\0"
  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

#write_bin(name, value) ⇒ Object

Write value to a registry value named name.

The value type is REG_SZ(write_s), REG_DWORD(write_i), or REG_BINARY(write_bin).



759
760
761
# File 'win32/lib/win32/registry.rb', line 759

def write_bin(name, value)
  write name, REG_BINARY, value.to_s
end

#write_i(name, value) ⇒ Object

Write value to a registry value named name.

The value type is REG_SZ(write_s), REG_DWORD(write_i), or REG_BINARY(write_bin).



749
750
751
# File 'win32/lib/win32/registry.rb', line 749

def write_i(name, value)
  write name, REG_DWORD, value.to_i
end

#write_s(name, value) ⇒ Object

Write value to a registry value named name.

The value type is REG_SZ(write_s), REG_DWORD(write_i), or REG_BINARY(write_bin).



739
740
741
# File 'win32/lib/win32/registry.rb', line 739

def write_s(name, value)
  write name, REG_SZ, value.to_s
end