/// <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"));
            }
        }
예제 #13
0
        //// ===========================================================================================================
        //// 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);
                    }
                }
            }
        }