mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 14:07:46 +08:00
Merge pull request #2514 from Schmitti91/v1.77.3-dev
Update Registry interaction capabilities.
This commit is contained in:
@@ -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
|
||||
}
|
||||
}
|
||||
29
mRemoteNG/Tools/WindowsRegistry/IRegistryRead.cs
Normal file
29
mRemoteNG/Tools/WindowsRegistry/IRegistryRead.cs
Normal 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
|
||||
}
|
||||
}
|
||||
20
mRemoteNG/Tools/WindowsRegistry/IRegistryWrite.cs
Normal file
20
mRemoteNG/Tools/WindowsRegistry/IRegistryWrite.cs
Normal 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}
|
||||
}
|
||||
}
|
||||
@@ -1,11 +0,0 @@
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
public enum RegistryHive
|
||||
{
|
||||
ClassesRoot,
|
||||
CurrentConfig,
|
||||
CurrentUser,
|
||||
Users,
|
||||
LocalMachine
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
211
mRemoteNG/Tools/WindowsRegistry/WindowsRegistryKey.cs
Normal file
211
mRemoteNG/Tools/WindowsRegistry/WindowsRegistryKey.cs
Normal 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
|
||||
}
|
||||
}
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user