Merge pull request #2514 from Schmitti91/v1.77.3-dev

Update Registry interaction capabilities.
This commit is contained in:
Dimitrij
2023-10-24 13:33:12 +01:00
committed by GitHub
7 changed files with 818 additions and 36 deletions

View File

@@ -1,8 +1,35 @@
namespace mRemoteNG.Tools.WindowsRegistry
using Microsoft.Win32;
using System.Collections.Generic;
using System.Runtime.Versioning;
namespace mRemoteNG.Tools.WindowsRegistry
{
[SupportedOSPlatform("windows")]
public interface IRegistry
{
Optional<string> GetKeyValue(RegistryHive hive, string keyPath, string propertyName);
string[] GetSubKeyNames(RegistryHive hive, string keyPath);
#region registry reader
string[] GetSubKeyNames(RegistryHive hive, string path);
Optional<string> GetPropertyValue(WindowsRegistryKey key);
Optional<string> GetPropertyValue(RegistryHive hive, string path, string name);
WindowsRegistryKey GetWindowsRegistryKey(RegistryHive hive, string path, string name);
WindowsRegistryKey GetWindowsRegistryKey(WindowsRegistryKey key);
List<WindowsRegistryKey> GetRegistryEntries(RegistryHive hive, string path);
List<WindowsRegistryKey> GetRegistryEntryiesRecursive(RegistryHive hive, string path);
#endregion
#region registry writer
void SetRegistryValue(WindowsRegistryKey key);
void SetRegistryValue(RegistryHive hive, string path, string name, object value, RegistryValueKind valueKind);
#endregion
#region converter
RegistryHive ConvertStringToRegistryHive(string hiveString);
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
#endregion
}
}

View File

@@ -0,0 +1,29 @@
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.Runtime.Versioning;
namespace mRemoteNG.Tools.WindowsRegistry
{
[SupportedOSPlatform("windows")]
public interface IRegistryRead
{
#region registry reader
string[] GetSubKeyNames(RegistryHive hive, string path);
Optional<string> GetPropertyValue(WindowsRegistryKey key);
Optional<string> GetPropertyValue(RegistryHive hive, string path, string name);
WindowsRegistryKey GetWindowsRegistryKey(RegistryHive hive, string path, string name);
WindowsRegistryKey GetWindowsRegistryKey(WindowsRegistryKey key);
List<WindowsRegistryKey> GetRegistryEntries(RegistryHive hive, string path);
List<WindowsRegistryKey> GetRegistryEntryiesRecursive(RegistryHive hive, string path);
#endregion
#region converter
RegistryHive ConvertStringToRegistryHive(string hiveString);
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
#endregion
}
}

View File

@@ -0,0 +1,20 @@
using Microsoft.Win32;
using System.Runtime.Versioning;
namespace mRemoteNG.Tools.WindowsRegistry
{
[SupportedOSPlatform("windows")]
public interface IRegistryWrite
{
#region registry writer
void SetRegistryValue(WindowsRegistryKey key);
void SetRegistryValue(RegistryHive hive, string path, string name, object value, RegistryValueKind valueKind);
#endregion
#region converter
RegistryHive ConvertStringToRegistryHive(string hiveString);
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
#endregion}
}
}

View File

@@ -1,11 +0,0 @@
namespace mRemoteNG.Tools.WindowsRegistry
{
public enum RegistryHive
{
ClassesRoot,
CurrentConfig,
CurrentUser,
Users,
LocalMachine
}
}

View File

@@ -1,39 +1,321 @@
using System;
using Microsoft.Win32;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Versioning;
using Microsoft.Win32;
using System.Security;
namespace mRemoteNG.Tools.WindowsRegistry
{
/// <summary>
/// This class interacting with the Windows Registry.
/// </summary>
[SupportedOSPlatform("windows")]
public class WindowsRegistry : IRegistry
public class WindowsRegistry : IRegistry, IRegistryRead, IRegistryWrite
{
public string[] GetSubKeyNames(RegistryHive hive, string keyPath)
#region public read
/// <summary>
/// Retrieves the names of subkeys under a specified registry key path.
/// </summary>
/// <param name="hive">The RegistryHive where the subkeys are located.</param>
/// <param name="path">The path to the registry key containing the subkeys.</param>
/// <returns>An array of strings containing the names of subkeys, or an empty array if no subkeys are found.</returns>
public string[] GetSubKeyNames(RegistryHive hive, string path)
{
keyPath.ThrowIfNull(nameof(keyPath));
if (hive == 0)
throw new ArgumentException("Unknown or unsupported RegistryHive value.", nameof(hive));
path.ThrowIfNull(nameof(path));
using (var key = OpenSubKey(hive, keyPath))
using (var key = OpenSubKey(hive, path))
{
return key.Any()
? key.First().GetSubKeyNames()
: new string[0];
}
}
/// <summary>
/// Retrieves the value of a specific property within a Windows Registry key and returns it as an Optional<string>.
/// </summary>
/// <param name="key">The WindowsRegistryKey containing information about the registry property.</param>
/// <returns>An Optional<string> containing the property value, or Optional<string>.Empty if the value is not found.</returns>
public Optional<string> GetPropertyValue(WindowsRegistryKey key)
{
if (!key.IsKeyReadable())
throw new InvalidOperationException("The Windows Registry key is not ready for reading.");
return GetPropertyValue(key.Hive, key.Path, key.Name);
}
public Optional<string> GetKeyValue(RegistryHive hive, string keyPath, string propertyName)
/// <summary>
/// Retrieves the value of a specific property within the Windows Registry and returns it as an Optional<string>.
/// </summary>
/// <param name="hive">The RegistryHive where the property is located.</param>
/// <param name="path">The path to the registry key containing the property.</param>
/// <param name="name">The name of the property to retrieve.</param>
/// <returns>An Optional<string> containing the property value, or Optional<string>.Empty if the value is not found.</returns>
public Optional<string> GetPropertyValue(RegistryHive hive, string path, string name)
{
keyPath.ThrowIfNull(nameof(keyPath));
propertyName.ThrowIfNull(nameof(propertyName));
if (hive == 0)
throw new ArgumentException("Unknown or unsupported RegistryHive value.", nameof(hive));
path.ThrowIfNull(nameof(path));
name.ThrowIfNull(nameof(name));
using (var key = OpenSubKey(hive, keyPath))
using (var key = OpenSubKey(hive, path))
{
if (!key.Any())
return Optional<string>.Empty;
return key.First().GetValue(propertyName) as string;
return key.First().GetValue(name) as string;
}
}
/// <summary>
/// Retrieves a WindowsRegistryKey object for a specific registry hive, path, and value name.
/// </summary>
/// <param name="hive">The RegistryHive of the key.</param>
/// <param name="path">The path of the key.</param>
/// <param name="name">The name of the value to retrieve.</param>
/// <returns>A WindowsRegistryKey object representing the specified registry key and value.</returns>
public WindowsRegistryKey GetWindowsRegistryKey(RegistryHive hive, string path, string name)
{
WindowsRegistryKey key = new WindowsRegistryKey
{
Hive = hive,
Path = path,
Name = name
};
return GetWindowsRegistryKey(key);
}
/// <summary>
/// Retrieves a WindowsRegistryKey object for a specific WindowsRegistryKey, populating its value and value kind.
/// </summary>
/// <param name="key">A WindowsRegistryKey object containing the hive, path, value name and more.</param>
/// <returns>A WindowsRegistryKey object representing the specified registry key and value, with value and value kind populated.</returns>
public WindowsRegistryKey GetWindowsRegistryKey(WindowsRegistryKey key)
{
if (!key.IsKeyReadable())
throw new InvalidOperationException("The Windows Registry key is not ready for reading.");
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(key.Hive, RegistryView.Default), subKey = baseKey.OpenSubKey(key.Path))
{
if (subKey != null)
{
var value = subKey.GetValue(key.Name);
if (value != null)
key.Value = value.ToString();
RegistryValueKind ValueKind;
if (TestValueKindExists(subKey, key.Name, out ValueKind))
key.ValueKind = ValueKind;
}
}
return key;
}
/// <summary>
/// Retrieves a list of registry entries (properties) and their values under a given key path.
/// </summary>
/// <param name="hive">The RegistryHive of the key path.</param>
/// <param name="path">The path of the key from which to retrieve values.</param>
/// <returns>A list of WindowsRegistryKey objects, each representing a value within the specified registry key path.</returns>
public List<WindowsRegistryKey> GetRegistryEntries(RegistryHive hive, string path)
{
if (hive == 0)
throw new ArgumentException("Unknown or unsupported RegistryHive value.", nameof(hive));
path.ThrowIfNull(nameof(path));
List<WindowsRegistryKey> list = new List<WindowsRegistryKey>();
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Default), key = baseKey.OpenSubKey(path))
{
if (key != null)
{
foreach (string valueName in key.GetValueNames())
{
list.Add(new WindowsRegistryKey
{
Hive = hive,
Path = path,
Name = valueName,
Value = key.GetValue(valueName).ToString(),
ValueKind = key.GetValueKind(valueName)
}
);
}
}
}
return list;
}
/// <summary>
/// Recursively retrieves registry entries under a given key path and its subkeys.
/// </summary>
/// <param name="hive">The RegistryHive of the key path.</param>
/// <param name="path">The path of the key from which to retrieve values.</param>
/// <returns>A list of WindowsRegistryKey objects, each representing a value within the specified registry key path.</returns>
public List<WindowsRegistryKey> GetRegistryEntryiesRecursive(RegistryHive hive, string path)
{
if (hive == 0)
throw new ArgumentException("Unknown or unsupported RegistryHive value.", nameof(hive));
path.ThrowIfNull(nameof(path));
List<WindowsRegistryKey> list = GetRegistryEntries(hive, path);
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Default), key = baseKey.OpenSubKey(path))
{
if (key != null)
{
foreach (string subPathName in key.GetSubKeyNames())
{
string subKey = $"{path}\\{subPathName}";
list.AddRange(GetRegistryEntryiesRecursive(hive, subKey));
}
}
}
return list;
}
#endregion
#region public write methods
/// <summary>
/// Sets the value of a specific property within a registry key using individual parameters.
/// </summary>
/// <param name="hive">The registry hive.</param>
/// <param name="path">The path to the registry key containing the property.</param>
/// <param name="name">The name of the property to set.</param>
/// <param name="value">The value to set for the property.</param>
/// <param name="valueKind">The data type of the value to set.</param>
public void SetRegistryValue(RegistryHive hive, string path, string name, object value, RegistryValueKind valueKind)
{
WindowsRegistryKey key = (new WindowsRegistryKey
{
Hive = hive,
Path = path,
Name = name,
Value = value.ToString(),
ValueKind = valueKind
});
CreateOrSetRegistryValue(key);
}
/// <summary>
/// Sets the value of a specific property within a registry key using the provided WindowsRegistryKey object.
/// </summary>
/// <param name="key">The WindowsRegistryKey object containing information about the registry property.</param>
public void SetRegistryValue(WindowsRegistryKey key)
{
CreateOrSetRegistryValue(key);
}
#endregion
#region public methods
/// <summary>
/// Converts a string representation of a Registry Hive to the corresponding RegistryHive enum value.
/// </summary>
/// <param name="hiveString">A string representation of a Registry Hive, not case-sensitive.</param>
/// <returns>The RegistryHive enum value corresponding to the provided string representation.</returns>
/// <exception cref="ArgumentException">Thrown if the provided string does not match a valid Registry Hive.</exception>
public RegistryHive ConvertStringToRegistryHive(string hiveString)
{
switch (hiveString.ToLower())
{
// ClassesRoot
case "hkcr":
case "hkey_classes_root":
case "classesroot":
return RegistryHive.ClassesRoot;
// CurrentUser
case "hkcu":
case "hkey_current_user":
case "currentuser":
return RegistryHive.CurrentUser;
// LocalMachine
case "hklm":
case "hkey_local_machine":
case "localmachine":
return RegistryHive.LocalMachine;
// Users
case "hku":
case "hkey_users":
case "users":
return RegistryHive.Users;
// CurrentConfig
case "hkcc":
case "hkey_current_config":
case "currentconfig":
return RegistryHive.CurrentConfig;
default:
throw new ArgumentException("Invalid registry hive string.", nameof(hiveString));
}
}
/// <summary>
/// Converts a string representation of a RegistryValueKind to the corresponding RegistryValueKind enum value.
/// </summary>
/// <param name="valueType">A string representation of a RegistryValueKind, not case-sensitive.</param>
/// <returns>The RegistryValueKind enum value corresponding to the provided string representation.</returns>
/// <exception cref="ArgumentException">Thrown if the provided string does not match a valid RegistryValueKind.</exception>
public RegistryValueKind ConvertStringToRegistryValueKind(string valueType)
{
switch (valueType.ToLower())
{
// REG_SZ
case "string":
case "reg_sz":
return RegistryValueKind.String;
// REG_DWORD
case "dword":
case "reg_dword":
return RegistryValueKind.DWord;
// REG_BINARY
case "binary":
case "reg_binary":
return RegistryValueKind.Binary;
// REG_QWORD
case "qword":
case "reg_qword":
return RegistryValueKind.QWord;
// REG_MULTI_SZ
case "multistring":
case "reg_multi_sz":
return RegistryValueKind.MultiString;
// REG_EXPAND_SZ
case "expandstring":
case "reg_expand_sz":
return RegistryValueKind.ExpandString;
default:
throw new ArgumentException("Invalid RegistryValueKind string representation.", nameof(valueType));
}
}
#endregion
#region private methods
/// <summary>
/// Opens a subkey within the Windows Registry under the specified hive and key path.
/// </summary>
/// <param name="hive">The Windows Registry hive where the subkey is located.</param>
/// <param name="keyPath">The path to the subkey to be opened.</param>
/// <returns>
/// A disposable optional object containing the opened registry subkey if successful;
/// otherwise, it returns an empty optional object.
/// </returns>
private DisposableOptional<RegistryKey> OpenSubKey(RegistryHive hive, string keyPath)
{
switch (hive)
@@ -52,5 +334,86 @@ namespace mRemoteNG.Tools.WindowsRegistry
throw new ArgumentOutOfRangeException(nameof(hive), hive, null);
}
}
/// <summary>
/// Attempts to retrieve the value kind of a specific property within a registry subkey.
/// </summary>
/// <param name="subKey">The registry subkey from which to retrieve the value kind.</param>
/// <param name="valueName">The name of the property for which to retrieve the value kind.</param>
/// <param name="valueKind">An output parameter that will contain the retrieved value kind, or RegistryValueKind.Unknown if the property or value kind is not found.</param>
/// <returns>True if the operation is successful, otherwise false.</returns>
private bool TestValueKindExists(RegistryKey subKey, string valueName, out RegistryValueKind valueKind)
{
// Set a default value
valueKind = RegistryValueKind.Unknown;
try
{
valueKind = subKey.GetValueKind(valueName);
return true;
}
catch (Exception)
{
return false;
}
}
/// <summary>
/// Creates or sets the value of a specific property within a registry key.
/// </summary>
/// <param name="key">The WindowsRegistryKey object containing information about the registry property.</param>
/// <exception cref="InvalidOperationException">Thrown when the Windows Registry key is not ready for writing.</exception>
/// <exception cref="SecurityException">Thrown when a security-related error occurs while accessing the registry.</exception>
/// <exception cref="IOException">Thrown when an I/O error occurs while accessing the registry.</exception>
/// <exception cref="UnauthorizedAccessException">Thrown when access to the registry is unauthorized.</exception>
/// <exception cref="Exception">Thrown for all other exceptions.</exception>
private void CreateOrSetRegistryValue(WindowsRegistryKey key)
{
try
{
if (!key.IsKeyWritable())
throw new InvalidOperationException("The Windows Registry key is not ready for writing.");
using (RegistryKey baseKey = RegistryKey.OpenBaseKey(key.Hive, RegistryView.Default), registryKey = baseKey.OpenSubKey(key.Path, true))
{
if (registryKey == null)
{
// The specified subkey doesn't exist, so create it.
using (RegistryKey newKey = baseKey.CreateSubKey(key.Path))
{
newKey.SetValue(key.Name, key.Value, key.ValueKind);
}
}
else
{
registryKey.SetValue(key.Name, key.Value, key.ValueKind);
}
}
}
catch (SecurityException ex)
{
// Handle or log SecurityException
// For example: log ex.Message
throw;
}
catch (IOException ex)
{
// Handle or log IOException
// For example: log ex.Message
throw;
}
catch (UnauthorizedAccessException ex)
{
// Handle or log UnauthorizedAccessException
// For example: log ex.Message
throw;
}
catch (Exception ex)
{
// For all other exceptions, log and rethrow
// For example: log ex.ToString()
throw;
}
}
#endregion
}
}

View File

@@ -0,0 +1,211 @@
using System;
using System.Runtime.Versioning;
using Microsoft.Win32;
namespace mRemoteNG.Tools.WindowsRegistry
{
/// <summary>
/// This class provides a convenient way to work with Windows Registry keys
/// by encapsulating information about a registry key, including its path,
/// name, value, and registry hive/type.
/// </summary>
[SupportedOSPlatform("windows")]
public class WindowsRegistryKey
{
#region properties
#region Property registryHive
public RegistryHive Hive
{
get { return _Hive; }
set
{
if (value == 0)
throw new ArgumentNullException("RegistryHive unknown.");
_Hive = value;
}
}
private RegistryHive _Hive { get; set; }
#endregion
#region Property path
public string Path
{
get { return _Path; }
set
{
value.ThrowIfNull(nameof(value));
_Path = value;
}
}
private string _Path { get; set; }
#endregion
#region Property name
public string Name
{
get { return _Name; }
set
{
value.ThrowIfNull(nameof(value));
_Name = value;
}
}
private string _Name { get; set; }
#endregion
#region Property valueKind
public RegistryValueKind ValueKind
{
get { return _ValueKind; }
set {
if (value == 0)
throw new ArgumentNullException("ValueKind unknown.");
_ValueKind = value;
// Check if Type is uninitialized (null)
if (_Type == null)
// Initialize Type if it's uninitialized
_Type = ConvertRegistryValueKindToType(value);
}
}
private RegistryValueKind _ValueKind;
#endregion
#region Property type
public Type Type
{
get { return _Type; }
set {
_Type = value;
// Check if ValueKind is uninitialized(0)
if (_ValueKind == 0)
// Initialize ValueKind if it's uninitialized
_ValueKind = ConvertTypeToRegistryValueKind(value);
}
}
private Type _Type;
#endregion
public string Value { get; set; }
#endregion
#region public methods
/// <summary>
/// Checks if the Windows Registry key is ready for reading by ensuring that the hive,
/// path, and name properties are set.
/// </summary>
/// <returns>True if the key is ready for reading, otherwise false.</returns>
public bool IsKeyReadable() {
return (IsHiveSet() && IsPathSet() && IsNameSet());
}
/// <summary>
/// Checks if the Windows Registry key is ready for a write operation.
/// The key is considered write-ready if none of the following conditions are met:
/// - The hive is set
/// - The registry value type is set
/// - The key path is set
/// - The value name is set
/// </summary>
/// <returns>Returns true if the key is write-ready, otherwise false.</returns>
public bool IsKeyWritable() {
return (IsHiveSet() && IsValueKindSet() && IsPathSet() && IsNameSet());
}
#endregion
#region private methods
/// <summary>
/// Converts a .NET data type to the corresponding RegistryValueKind.
/// </summary>
/// <param name="valueType">The .NET data type to convert.</param>
/// <returns>The corresponding RegistryValueKind.</returns>
private RegistryValueKind ConvertTypeToRegistryValueKind(Type valueType)
{
switch (Type.GetTypeCode(valueType))
{
case TypeCode.String:
return RegistryValueKind.String;
case TypeCode.Int32:
return RegistryValueKind.DWord;
case TypeCode.Int64:
return RegistryValueKind.QWord;
case TypeCode.Boolean:
return RegistryValueKind.DWord;
case TypeCode.Byte:
return RegistryValueKind.Binary;
/*
case TypeCode.Single:
return RegistryValueKind;
case TypeCode.Double:
return RegistryValueKind.String;
case TypeCode.DateTime:
return RegistryValueKind.String; // DateTime can be stored as a string or other types
case TypeCode.Char:
return RegistryValueKind.String; // Char can be stored as a string or other types
case TypeCode.Decimal:
return RegistryValueKind.String; // Decimal can be stored as a string or other types
*/
default:
return RegistryValueKind.String; // Default to String for unsupported types
}
}
/// <summary>
/// Converts a RegistryValueKind enumeration value to its corresponding .NET Type.
/// </summary>
/// <param name="valueKind">The RegistryValueKind value to be converted.</param>
/// <returns>The .NET Type that corresponds to the given RegistryValueKind.</returns>
private Type ConvertRegistryValueKindToType(RegistryValueKind valueKind)
{
switch (valueKind)
{
case RegistryValueKind.String:
case RegistryValueKind.ExpandString:
return typeof(string);
case RegistryValueKind.DWord:
return typeof(int);
case RegistryValueKind.QWord:
return typeof(long);
case RegistryValueKind.Binary:
return typeof(byte[]);
case RegistryValueKind.MultiString:
return typeof(string[]);
case RegistryValueKind.Unknown:
default:
return typeof(object);
}
}
private bool IsHiveSet()
{
return Hive != 0;
}
private bool IsValueKindSet()
{
return ValueKind != 0;
}
private bool IsPathSet()
{
return Path != null; ;
//return !string.IsNullOrEmpty(Path);
}
private bool IsNameSet()
{
return Name != null;
}
private bool IsValueSet()
{
return !string.IsNullOrEmpty(Value);
}
#endregion
}
}

View File

@@ -1,5 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Win32;
using mRemoteNG.Tools.WindowsRegistry;
using NUnit.Framework;
@@ -7,44 +9,185 @@ namespace mRemoteNGTests.Tools.Registry
{
public class WindowsRegistryTests
{
private WindowsRegistry _registry;
private IRegistry _registry;
private IRegistryRead _registryReader;
private IRegistryWrite _registryWriter;
[SetUp]
public void Setup()
{
_registry = new WindowsRegistry();
_registryReader = new WindowsRegistry();
_registryWriter = new WindowsRegistry();
}
#region GetSubKeyNames() tests
[Test]
public void CanGetSubkeyNames()
{
var subKeyNames = _registry.GetSubKeyNames(RegistryHive.CurrentUser, "Software");
var subKeyNames = _registryReader.GetSubKeyNames(RegistryHive.CurrentUser, "Software");
Assert.That(subKeyNames, Does.Contain("Microsoft"));
}
[Test]
public void GetSubkeyNamesThrowsIfGivenNullKeyPath()
{
Assert.Throws<ArgumentNullException>(() => _registry.GetSubKeyNames(RegistryHive.CurrentUser, null));
Assert.Throws<ArgumentNullException>(() => _registryReader.GetSubKeyNames(RegistryHive.CurrentUser, null));
}
[Test]
public void CanGetKeyValue()
public void GetSubkeyNamesThrowsIfGivenUnknownHive()
{
var keyValue = _registry.GetKeyValue(RegistryHive.ClassesRoot, @".dll\PersistentHandler", "");
Assert.Throws<ArgumentException>(() => _registryReader.GetSubKeyNames(new RegistryHive(), "Software"));
}
#endregion
#region GetPropertyValue() tests
[Test]
public void CanGetPropertyValue()
{
var keyValue = _registryReader.GetPropertyValue(RegistryHive.ClassesRoot, @".dll\PersistentHandler", "");
Assert.That(keyValue.FirstOrDefault(), Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
}
[Test]
public void GetKeyValueThrowsIfGivenNullKeyPath()
public void CanGetPropertyValueByRegistryKeyObject()
{
Assert.Throws<ArgumentNullException>(() => _registry.GetKeyValue(RegistryHive.CurrentUser, null, ""));
WindowsRegistryKey key = new WindowsRegistryKey
{
Hive = RegistryHive.ClassesRoot,
Path = @".dll\PersistentHandler",
Name = ""
};
var keyValue = _registryReader.GetPropertyValue(key);
Assert.That(keyValue.FirstOrDefault(), Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
}
[Test]
public void GetPropertyValueThrowsIfGivenNullKeyPath()
{
Assert.Throws<ArgumentNullException>(() => _registryReader.GetPropertyValue(RegistryHive.CurrentUser, null, ""));
}
[Test]
public void GetKeyValueThrowsIfGivenNullPropertyName()
public void GetPropertyValueThrowsIfGivenNullPropertyName()
{
Assert.Throws<ArgumentNullException>(() => _registry.GetKeyValue(RegistryHive.CurrentUser, "", null));
Assert.Throws<ArgumentNullException>(() => _registryReader.GetPropertyValue(RegistryHive.CurrentUser, "", null));
}
#endregion
#region GetWindowsRegistryKey() tests
[Test]
public void CanGetWindowsRegistryKey()
{
WindowsRegistryKey keyValue = _registryReader.GetWindowsRegistryKey(RegistryHive.ClassesRoot, @".dll\PersistentHandler", "");
Assert.That(keyValue.Value, Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
}
[Test]
public void CanGetWindowsRegistryKeyByObject()
{
WindowsRegistryKey key = new WindowsRegistryKey
{
Hive = RegistryHive.ClassesRoot,
Path = @".dll\PersistentHandler",
Name = ""
};
WindowsRegistryKey keyValue = _registryReader.GetWindowsRegistryKey(key);
Assert.That(keyValue.Value, Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
}
[Test]
public void CanGetWindowsRegistryKeyForKeyNotExists()
{
// No exception. Only null value
WindowsRegistryKey keyValue = _registryReader.GetWindowsRegistryKey(RegistryHive.LocalMachine, @"Software\Testabcdefg", "abcdefg");
Assert.That(keyValue.Value, Is.EqualTo(null));
}
[Test]
public void GetWindowsRegistryThrowNotReadable()
{
WindowsRegistryKey key = new WindowsRegistryKey
{
Hive = RegistryHive.ClassesRoot,
};
Assert.Throws<InvalidOperationException>(() => _registryReader.GetWindowsRegistryKey(key));
}
#endregion
#region GetRegistryEntries() + Recurse tests
[Test]
public void CanGetRegistryEntries()
{
List<WindowsRegistryKey> keys = _registryReader.GetRegistryEntries(RegistryHive.LocalMachine, @"HARDWARE\DESCRIPTION\System\BIOS");
Assert.That(keys.Count, Is.Not.EqualTo(0));
}
[Test]
public void CanGetRegistryEntriesRecurse()
{
List<WindowsRegistryKey> keys = _registryReader.GetRegistryEntryiesRecursive(RegistryHive.LocalMachine, @"SOFTWARE\Microsoft\Windows\Windows Search");
Assert.That(keys.Count, Is.Not.EqualTo(0));
}
#endregion
#region new WindowsRegistryKey() tests
[Test]
public void IsWindowsRegistryKeyValid()
{
// Tests property rules of WindowsRegistryKey
WindowsRegistryKey key = new WindowsRegistryKey();
Assert.Multiple(() =>
{
Assert.DoesNotThrow(() => key.Hive = RegistryHive.CurrentUser);
Assert.DoesNotThrow(() => key.ValueKind = RegistryValueKind.String);
Assert.DoesNotThrow(() => key.Path = "Software");
Assert.DoesNotThrow(() => key.Name = "NotThereButOK");
//Assert.DoesNotThrow(() => key.Value = "Equal", "");
});
}
[Test]
public void WindowsRegistryKeyThrowHiveNullException()
{
WindowsRegistryKey key = new WindowsRegistryKey();
Assert.Throws<ArgumentNullException>(() => key.Hive = 0, "Expected IsHiveValid to throw ArgumentNullException");
}
[Test]
public void WindowsRegistryKeyThrowValueKindNullException()
{
WindowsRegistryKey key = new WindowsRegistryKey();
Assert.Throws<ArgumentNullException>(() => key.ValueKind = 0, "Expected IsValueKindValid to throw ArgumentNullException");
}
[Test]
public void WindowsRegistryKeyThrowPathNullException()
{
WindowsRegistryKey key = new WindowsRegistryKey();
Assert.Throws<ArgumentNullException>(() => key.Path = null, "Expected IsPathValid to throw ArgumentNullException");
}
[Test]
public void WindowsRegistryKeyThrowNameNullException()
{
WindowsRegistryKey key = new WindowsRegistryKey();
Assert.Throws<ArgumentNullException>(() => key.Name = null, "Expected IsNameValid to throw ArgumentNullException");
}
#endregion
#region SetRegistryValue() tests
[Test]
public void CanSetRegistryValue()
{
Assert.DoesNotThrow(() => _registryWriter.SetRegistryValue(RegistryHive.CurrentUser, @"SOFTWARE\mRemoteNGTest", "TestKey", "A value string", RegistryValueKind.String));
}
[Test]
public void SetRegistryValueThrowAccessDenied()
{
Assert.Throws<UnauthorizedAccessException>(() => _registryWriter.SetRegistryValue(RegistryHive.LocalMachine, @"SOFTWARE\mRemoteNGTest", "TestKey", "A value string", RegistryValueKind.String));
}
#endregion
}
}