summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHiroshi SHIBATA <hsbt@ruby-lang.org>2024-10-04 14:37:09 +0900
committerHiroshi SHIBATA <hsbt@ruby-lang.org>2024-10-09 13:55:45 +0900
commit4eda289a13c61347c28cbb327d07e5064583904d (patch)
tree26b51eb1affda8db6af44bcf0bd4fb03d2b8aedd
parentfc2efc2bdb5e8f48b83757d8de1ae90750150e84 (diff)
Sync from ruby/win32-registry
Notes
Notes: Merged: https://github.com/ruby/ruby/pull/11791
-rw-r--r--ext/win32/lib/win32/registry.rb20
-rw-r--r--ext/win32/win32-registry.gemspec29
-rw-r--r--test/win32/test_registry.rb209
3 files changed, 220 insertions, 38 deletions
diff --git a/ext/win32/lib/win32/registry.rb b/ext/win32/lib/win32/registry.rb
index c801b1327b..e84653d945 100644
--- a/ext/win32/lib/win32/registry.rb
+++ b/ext/win32/lib/win32/registry.rb
@@ -69,11 +69,7 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
WCHAR_NUL = "\0".encode(WCHAR).freeze
WCHAR_CR = "\r".encode(WCHAR).freeze
WCHAR_SIZE = WCHAR_NUL.bytesize
- begin
- LOCALE = Encoding.find(Encoding.locale_charmap)
- rescue ArgumentError
- LOCALE = Encoding::UTF_8
- end
+ LOCALE = Encoding::UTF_8
class Registry
@@ -567,9 +563,16 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
end
#
- # Enumerate values.
+ # Enumerate all values in this registry path.
+ #
+ # For each value it yields key, type and data.
+ #
+ # key is a String which contains name of key.
+ # type is a type contant kind of Win32::Registry::REG_*
+ # data is the value of this key.
#
def each_value
+ return enum_for(:each_value) unless block_given?
index = 0
while true
begin
@@ -600,13 +603,16 @@ For detail, see the MSDN[http://msdn.microsoft.com/library/en-us/sysinfo/base/pr
end
#
- # Enumerate subkeys.
+ # Enumerate all subkeys.
+ #
+ # For each subkey it yields subkey and wtime.
#
# subkey is String which contains name of subkey.
# wtime is last write time as FILETIME (64-bit integer).
# (see Registry.wtime2time)
#
def each_key
+ return enum_for(:each_key) unless block_given?
index = 0
while true
begin
diff --git a/ext/win32/win32-registry.gemspec b/ext/win32/win32-registry.gemspec
new file mode 100644
index 0000000000..b6df247574
--- /dev/null
+++ b/ext/win32/win32-registry.gemspec
@@ -0,0 +1,29 @@
+# frozen_string_literal: true
+Gem::Specification.new do |spec|
+ spec.name = "win32-registry"
+ spec.version = "0.0.1"
+ spec.authors = ["U.Nakamura"]
+ spec.email = ["usa@garbagecollect.jp"]
+
+ spec.summary = %q{Provides an interface to the Windows Registry in Ruby}
+ spec.description = spec.summary
+ spec.homepage = "https://github.com/ruby/win32-registry"
+ spec.required_ruby_version = ">= 2.6.0"
+
+ spec.metadata["homepage_uri"] = spec.homepage
+ spec.metadata["source_code_uri"] = spec.homepage
+
+ # Specify which files should be added to the gem when it is released.
+ # The `git ls-files -z` loads the files in the RubyGem that have been added into git.
+ spec.files = Dir.chdir(__dir__) do
+ `git ls-files -z`.split("\x0").reject do |f|
+ (File.expand_path(f) == __FILE__) ||
+ f.start_with?(*%w[bin/ test/ spec/ features/ .git .github appveyor Gemfile])
+ end
+ end
+ spec.bindir = "exe"
+ spec.executables = spec.files.grep(%r{\Aexe/}) { |f| File.basename(f) }
+ spec.require_paths = ["lib"]
+
+ spec.add_dependency "fiddle", "~> 1.0"
+end
diff --git a/test/win32/test_registry.rb b/test/win32/test_registry.rb
index 02cafc09b0..8a98405a79 100644
--- a/test/win32/test_registry.rb
+++ b/test/win32/test_registry.rb
@@ -1,3 +1,5 @@
+# frozen_string_literal: true
+
if /mswin|mingw|cygwin/ =~ RUBY_PLATFORM
begin
require 'win32/registry'
@@ -10,7 +12,19 @@ end
if defined?(Win32::Registry)
class TestWin32Registry < Test::Unit::TestCase
COMPUTERNAME = 'SYSTEM\\CurrentControlSet\\Control\\ComputerName\\ComputerName'
- VOLATILE_ENVIRONMENT = 'Volatile Environment'
+
+ private def backslachs(path)
+ path.gsub("/", "\\")
+ end
+
+ TEST_REGISTRY_KEY = "SOFTWARE/ruby-win32-registry-test/"
+
+ def setup
+ Win32::Registry::HKEY_CURRENT_USER.open(backslachs(File.dirname(TEST_REGISTRY_KEY))) do |reg|
+ reg.delete_key File.basename(TEST_REGISTRY_KEY), true
+ end
+ rescue Win32::Registry::Error
+ end
def test_predefined
assert_predefined_key Win32::Registry::HKEY_CLASSES_ROOT
@@ -24,6 +38,38 @@ if defined?(Win32::Registry)
assert_predefined_key Win32::Registry::HKEY_DYN_DATA
end
+ def test_open_no_block
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)).close
+
+ reg = Win32::Registry::HKEY_CURRENT_USER.open(backslachs(TEST_REGISTRY_KEY), Win32::Registry::KEY_ALL_ACCESS)
+ assert_kind_of Win32::Registry, reg
+ assert_equal true, reg.open?
+ assert_equal false, reg.created?
+ reg["test"] = "abc"
+ reg.close
+ assert_raise(Win32::Registry::Error) do
+ reg["test"] = "abc"
+ end
+ end
+
+ def test_open_with_block
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)).close
+
+ regs = []
+ Win32::Registry::HKEY_CURRENT_USER.open(backslachs(TEST_REGISTRY_KEY), Win32::Registry::KEY_ALL_ACCESS) do |reg|
+ regs << reg
+ assert_equal true, reg.open?
+ assert_equal false, reg.created?
+ reg["test"] = "abc"
+ end
+
+ assert_equal 1, regs.size
+ assert_kind_of Win32::Registry, regs[0]
+ assert_raise(Win32::Registry::Error) do
+ regs[0]["test"] = "abc"
+ end
+ end
+
def test_class_open
name1, keys1 = Win32::Registry.open(Win32::Registry::HKEY_LOCAL_MACHINE, "SYSTEM") do |reg|
assert_predicate reg, :open?
@@ -46,32 +92,145 @@ if defined?(Win32::Registry)
end
end
- def test_create
+ def test_create_volatile
desired = Win32::Registry::KEY_ALL_ACCESS
option = Win32::Registry::REG_OPTION_VOLATILE
- Win32::Registry::HKEY_CURRENT_USER.open(VOLATILE_ENVIRONMENT, desired) do |reg|
- v = self.class.unused_value(reg)
- begin
- reg.create(v, desired, option) {}
- ensure
- reg.delete_key(v, true)
- end
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY), desired) do |reg|
+ reg.create("volkey", desired, option) {}
+ reg.delete_key("volkey", true)
+ end
+ end
+
+ def test_create_no_block
+ reg = Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY))
+ assert_kind_of Win32::Registry, reg
+ assert_equal true, reg.open?
+ assert_equal true, reg.created?
+ reg["test"] = "abc"
+ reg.close
+ assert_equal false, reg.open?
+ assert_raise(Win32::Registry::Error) do
+ reg["test"] = "abc"
+ end
+ end
+
+ def test_create_with_block
+ regs = []
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ regs << reg
+ reg["test"] = "abc"
+ assert_equal true, reg.open?
+ assert_equal true, reg.created?
+ end
+
+ assert_equal 1, regs.size
+ assert_kind_of Win32::Registry, regs[0]
+ assert_equal false, regs[0].open?
+ assert_raise(Win32::Registry::Error) do
+ regs[0]["test"] = "abc"
end
end
def test_write
desired = Win32::Registry::KEY_ALL_ACCESS
- Win32::Registry::HKEY_CURRENT_USER.open(VOLATILE_ENVIRONMENT, desired) do |reg|
- v = self.class.unused_value(reg)
- begin
- reg.write_s(v, "data")
- assert_equal [Win32::Registry::REG_SZ, "data"], reg.read(v)
- reg.write_i(v, 0x5fe79027)
- assert_equal [Win32::Registry::REG_DWORD, 0x5fe79027], reg.read(v)
- ensure
- reg.delete(v)
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY), desired) do |reg|
+ reg.write_s("key1", "data")
+ assert_equal [Win32::Registry::REG_SZ, "data"], reg.read("key1")
+ reg.write_i("key2", 0x5fe79027)
+ assert_equal [Win32::Registry::REG_DWORD, 0x5fe79027], reg.read("key2")
+ end
+ end
+
+ def test_accessors
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ assert_kind_of Integer, reg.hkey
+ assert_kind_of Win32::Registry, reg.parent
+ assert_equal "HKEY_CURRENT_USER", reg.parent.name
+ assert_equal "SOFTWARE\\ruby-win32-registry-test\\", reg.keyname
+ assert_equal Win32::Registry::REG_CREATED_NEW_KEY, reg.disposition
+ end
+ end
+
+ def test_name
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ assert_equal "HKEY_CURRENT_USER\\SOFTWARE\\ruby-win32-registry-test\\", reg.name
+ end
+ end
+
+ def test_keys
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ reg.create("key1")
+ assert_equal ["key1"], reg.keys
+ end
+ end
+
+ def test_each_key
+ keys = []
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ reg.create("key1")
+ reg.each_key { |*a| keys << a }
+ end
+ assert_equal [2], keys.map(&:size)
+ assert_equal ["key1"], keys.map(&:first)
+ assert_in_delta Win32::Registry.time2wtime(Time.now), keys[0][1], 10_000_000_000, "wtime should roughly match Time.now"
+ end
+
+ def test_each_key_enum
+ keys = nil
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ reg.create("key1")
+ reg.create("key2")
+ reg.create("key3")
+ reg["value1"] = "abcd"
+ keys = reg.each_key.to_a
+ end
+ assert_equal 3, keys.size
+ assert_equal [2, 2, 2], keys.map(&:size)
+ assert_equal ["key1", "key2", "key3"], keys.map(&:first)
+ end
+
+ def test_values
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ reg.create("key1")
+ reg["value1"] = "abcd"
+ assert_equal ["abcd"], reg.values
+ end
+ end
+
+ def test_each_value
+ vals = []
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ reg.create("key1")
+ reg["value1"] = "abcd"
+ reg.each_value { |*a| vals << a }
+ end
+ assert_equal [["value1", Win32::Registry::REG_SZ, "abcd"]], vals
+ end
+
+ def test_each_value_enum
+ vals = nil
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ reg.create("key1")
+ reg["value1"] = "abcd"
+ reg["value2"] = 42
+ vals = reg.each_value.to_a
+ end
+ assert_equal [["value1", Win32::Registry::REG_SZ, "abcd"],
+ ["value2", Win32::Registry::REG_DWORD, 42]], vals
+ end
+
+ def test_utf8_encoding
+ keys = []
+ Win32::Registry::HKEY_CURRENT_USER.create(backslachs(TEST_REGISTRY_KEY)) do |reg|
+ reg.create("abc EUR")
+ reg.create("abc €")
+ reg.each_key do |subkey|
+ keys << subkey
end
end
+
+ assert_equal [Encoding::UTF_8] * 2, keys.map(&:encoding)
+ assert_equal ["abc EUR", "abc €"], keys
end
private
@@ -79,19 +238,7 @@ if defined?(Win32::Registry)
def assert_predefined_key(key)
assert_kind_of Win32::Registry, key
assert_predicate key, :open?
- assert_not_predicate key, :created?
- end
-
- class << self
- def unused_value(reg, prefix = "Test_", limit = 100, fail: true)
- limit.times do
- v = + rand(0x100000).to_s(36)
- reg.read(v)
- rescue
- return v
- end
- omit "Unused value not found in #{reg}" if fail
- end
+ refute_predicate key, :created?
end
end
end