/// <summary> /// Writes a value to the Windows registryKey. /// </summary> /// <typeparam name="T">The type of value that is written (<see cref="RegistryReadValueCommand{T}"/>).</typeparam> /// <param name="command">The command to execute.</param> /// <param name="logger">The logger to use.</param> /// <returns>A response indicating success and the written value, or failure with error details.</returns> public IServiceCommandResponse ExecuteWrite <T>(RegistryWriteValueCommand <T> command, ILogger logger) { Param.VerifyNotNull(command, nameof(command)); Param.VerifyNotNull(logger, nameof(logger)); IServiceCommandResponse response; try { var registryHive = (RegistryHive)Enum.Parse(typeof(RegistryHive), command.BaseKey.ToString()); using (IWin32RegistryKey baseKey = _registry.OpenBaseKey(registryHive, RegistryView.Registry64)) using (IWin32RegistryKey subKey = baseKey.CreateSubKey(command.Key, writable: true)) { subKey.SetValue(command.ValueName, command.Value, TypeToRegistryValueKind(typeof(T))); response = ServiceCommandResponse.Create(command.CommandName, command.Value); } } catch (Exception e) { response = ServiceCommandResponse.CreateError( command.CommandName, ServiceErrorInfo.RegistryWriteError( RegistryPath.HiveToWin32Name(RegistryPath.BaseKeyToHive(command.BaseKey)), command.Key, command.ValueName, e)); logger.LogError(response.ErrorMessage); } return(response); }
//// =========================================================================================================== //// Methods //// =========================================================================================================== /// <summary> /// Reads a value from the Windows registryKey. /// </summary> /// <typeparam name="T">The type of value that is read (<see cref="RegistryReadValueCommand{T}"/>).</typeparam> /// <param name="command">The command to execute.</param> /// <param name="logger">The logger to use.</param> /// <returns>A response indicating success and the read value, or failure with error details.</returns> public IServiceCommandResponse ExecuteRead <T>(RegistryReadValueCommand <T> command, ILogger logger) { Param.VerifyNotNull(command, nameof(command)); Param.VerifyNotNull(logger, nameof(logger)); ServiceCommandResponse response; try { var registryHive = (RegistryHive)Enum.Parse(typeof(RegistryHive), command.BaseKey.ToString()); using (IWin32RegistryKey baseKey = _registry.OpenBaseKey(registryHive, RegistryView.Registry64)) using (IWin32RegistryKey subKey = baseKey.OpenSubKey(command.Key, writable: false)) { object value = subKey?.GetValue(command.ValueName, command.DefaultValue) ?? command.DefaultValue; response = ServiceCommandResponse.Create(command.CommandName, value); } } catch (Exception e) { response = ServiceCommandResponse.CreateError( command.CommandName, ServiceErrorInfo.RegistryReadError( RegistryPath.HiveToWin32Name(RegistryPath.BaseKeyToHive(command.BaseKey)), command.Key, command.ValueName, e)); logger.LogError(response.ErrorMessage); } return(response); }
private IWin32RegistryKey CreateSubKey(string fullPath, bool writable) { IWin32RegistryKey subKey = OpenSubKey(fullPath, writable); if (subKey == null) { subKey = new Key(this, fullPath, writable); _keys.Add(fullPath, null); // Also add any nested paths string[] nestedPathSegments = fullPath.Split('\\'); while (nestedPathSegments.Length > 1) { string path = string.Join("\\", nestedPathSegments.Take(nestedPathSegments.Length - 1)); if (_keys.ContainsKey(path)) { break; } _keys.Add(path, null); nestedPathSegments = path.Split('\\'); } } return(subKey); }
public void OpenSubKey_should_return_null_if_the_key_does_not_exist() { var registry = new FakeRegistry(); using (IWin32RegistryKey hkcu = registry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) { hkcu.OpenSubKey("NotThere").Should().BeNull(); } }
public void GetValue_should_return_the_default_value_if_not_present() { var registry = new FakeRegistry(); using (IWin32RegistryKey hkcu = registry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) using (IWin32RegistryKey subKey = hkcu.CreateSubKey("SubKey")) { subKey.GetValue("NoValue", 100).Should().Be(100); } }
public void CreateSubKey_should_create_a_key_if_it_does_not_exist() { var registry = new FakeRegistry(); using (IWin32RegistryKey hkcu = registry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) using (hkcu.CreateSubKey("SubKey")) { hkcu.OpenSubKey("SubKey").Should().NotBeNull(); } }
public void SetValue_should_create_the_value_if_not_present() { var registry = new FakeRegistry(); using (IWin32RegistryKey hkcu = registry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) using (IWin32RegistryKey subKey = hkcu.CreateSubKey("SubKey", writable: true)) { subKey.SetValue("ValueName", 123, RegistryValueKind.DWord); subKey.GetValue("ValueName").Should().Be(123); } }
public void SetValue_should_throw_an_UnauthorizedAccessException_if_it_is_not_writable() { var registry = new FakeRegistry(); using (IWin32RegistryKey hkcu = registry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) using (IWin32RegistryKey subKey = hkcu.CreateSubKey("SubKey", writable: false)) { Action action = () => subKey.SetValue("ValueName", 123, RegistryValueKind.DWord); action.Should().ThrowExactly <UnauthorizedAccessException>(); } }
public void OpenSubKey_and_CreateSubKey_should_accept_nested_paths() { var registry = new FakeRegistry(); using (IWin32RegistryKey hkcu = registry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) using (IWin32RegistryKey subKey = hkcu.CreateSubKey(@"a\b\c")) { hkcu.OpenSubKey(@"a\b\c").Should().NotBeNull(); hkcu.OpenSubKey(@"a\b").Should().NotBeNull(); hkcu.OpenSubKey(@"a").Should().NotBeNull(); } }
public void OpenSubKey_should_throw_ObjectDisposedException_if_closed() { var registry = new FakeRegistry(); using (IWin32RegistryKey hkcu = registry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) { IWin32RegistryKey subKey = hkcu.CreateSubKey("SubKey", writable: false); subKey.Dispose(); Action action = () => subKey.OpenSubKey("ValueName"); action.Should().ThrowExactly <ObjectDisposedException>(); } }
public void Closing_a_base_key_does_not_throw_ObjectDisposedException() { var realKey = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64); realKey.Dispose(); Action action = () => realKey.CreateSubKey(TestPath); action.Should().NotThrow(); var fakeRegistry = new FakeRegistry(); IWin32RegistryKey fakeKey = fakeRegistry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64); fakeKey.Dispose(); action = () => fakeKey.CreateSubKey(TestPath); action.Should().NotThrow(); }
public void An_operation_on_a_disposed_key_throws_the_same_exception_as_the_real_registry() { Exception expectedException = null; using (var hkcu = RegistryKey.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) { RegistryKey testKey = hkcu.CreateSubKey(TestPath, writable: false); testKey.Dispose(); try { testKey.GetValue("TestValue"); } catch (Exception e) { expectedException = e; } finally { hkcu.DeleteSubKey(TestPath, throwOnMissingSubKey: false); } expectedException.Should().NotBeNull(); } var fakeRegistry = new FakeRegistry(); using (IWin32RegistryKey hkcu = fakeRegistry.OpenBaseKey(RegistryHive.CurrentUser, RegistryView.Registry64)) { IWin32RegistryKey testKey = hkcu.CreateSubKey(TestPath, writable: false); testKey.Dispose(); // ReSharper disable once AccessToDisposedClosure Action action = () => testKey.SetValue("TestValue", 123, RegistryValueKind.DWord); action.Should() .Throw <Exception>() .And.Should() .BeEquivalentTo( expectedException, options => options.Excluding(e => e.TargetSite) .Excluding(e => e.StackTrace) .Excluding(e => e.Source) .Excluding(info => info.SelectedMemberInfo.Name == "IPForWatsonBuckets")); } }
//// =========================================================================================================== //// Constructors //// =========================================================================================================== /// <summary> /// Initializes a new instance of the <see cref="FakeRegistry"/> class with the specified keys and value. /// </summary> /// <param name="keysAndValues"> /// The string needs to be in the form "BASE\SubKey[\Value=123]", where BASE is one of <c>HKEY_CLASSES_ROOT</c> /// (or <c>HKCR</c>), <c>HKEY_CURRENT_USER</c> (or <c>HKCU</c>), <c>HKEY_LOCAL_MACHINE</c> (or <c>HKLM</c>), or /// HKEY_USERS (or <c>HKU</c>). The value can either be an integer or a string with single or double quotes. /// </param> public FakeRegistry(params string[] keysAndValues) { foreach (string keyAndValue in keysAndValues) { var parsedPath = RegistryPath.Parse(keyAndValue); using (IWin32RegistryKey key = OpenBaseKey(parsedPath.Hive, RegistryView.Registry64) .CreateSubKey(parsedPath.Path, writable: true)) { if (!string.IsNullOrEmpty(parsedPath.ValueName)) { RegistryValueKind kind = parsedPath.Value is string ?RegistryValueKind.String : RegistryValueKind.DWord; key.SetValue(parsedPath.ValueName, parsedPath.Value, kind); } } } }