mirror of
https://github.com/mRemoteNG/mRemoteNG.git
synced 2026-02-17 22:11:48 +08:00
Merge pull request #2601 from xRushG/RegSettings
Enhancement of Registry Settings capabilities
This commit is contained in:
@@ -6,19 +6,27 @@ namespace mRemoteNG.App.Info
|
||||
[SupportedOSPlatform("windows")]
|
||||
public static class WindowsRegistryInfo
|
||||
{
|
||||
#region general parameters
|
||||
#region General Parameters
|
||||
|
||||
public const RegistryHive Hive = RegistryHive.LocalMachine;
|
||||
public const string RootKey = "SOFTWARE\\mRemoteNG";
|
||||
private const string OptionsSubKey = "Options";
|
||||
|
||||
#endregion
|
||||
|
||||
#region subkey location parameters
|
||||
#region Key Locations
|
||||
|
||||
// Credential
|
||||
public const string CredentialSubkey = RootKey + "\\Credentials"; // Registry subkey for general credential settings
|
||||
public const string CredentialOptionsSubkey = RootKey + "\\Credentials\\Options"; // Registry subkey for credential options within the credential settings
|
||||
// Registry subkey for general application credentials settings
|
||||
// Registry subkey for credentials options page settings
|
||||
public const string Credential = RootKey + "\\Credentials";
|
||||
public const string CredentialOptions = Credential + "\\" + OptionsSubKey;
|
||||
|
||||
// Updates
|
||||
public const string UpdateSubkey = RootKey + "\\Updates"; // Registry subkey for general update settings
|
||||
public const string UpdateOptionsSubkey = RootKey + "\\Updates\\Options"; // Registry subkey for update options within the update settings
|
||||
// Registry subkey for general application update settings
|
||||
// Registry subkey for updates options page settings
|
||||
public const string Update = RootKey + "\\Updates";
|
||||
public const string UpdateOptions = Update + "\\" + OptionsSubKey;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -11,28 +11,23 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// Benefits: Simplified code, enhances maintainability, and ensures consistency. #ReadOnly
|
||||
public static class CommonRegistrySettings
|
||||
{
|
||||
private static readonly IRegistryAdvancedRead _WindowsRegistry = new WindowsRegistryAdvanced();
|
||||
private static readonly RegistryHive _Hive = WindowsRegistryInfo.Hive;
|
||||
|
||||
private const string __Update = WindowsRegistryInfo.UpdateSubkey;
|
||||
private const string __Credential = WindowsRegistryInfo.CredentialSubkey;
|
||||
|
||||
#region general update registry settings
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether searching for updates is allowed. If false, there is no way to update directly from mRemoteNG.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Default value is true, which allows check for updates.
|
||||
/// </remarks>
|
||||
public static bool AllowCheckForUpdates { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Update, nameof(AllowCheckForUpdates), true);
|
||||
public static bool AllowCheckForUpdates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether automatic search for updates is allowed.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Default value is true, which allows check for updates automaticaly.
|
||||
/// Default value is true, which allows check for updates automatically.
|
||||
/// </remarks>
|
||||
public static bool AllowCheckForUpdatesAutomatical { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Update, nameof(AllowCheckForUpdatesAutomatical), AllowCheckForUpdates);
|
||||
public static bool AllowCheckForUpdatesAutomatical { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a manual search for updates is allowed.
|
||||
@@ -40,39 +35,65 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// <remarks>
|
||||
/// The default value is true, enabling the manual check for updates.
|
||||
/// </remarks>
|
||||
public static bool AllowCheckForUpdatesManual { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Update, nameof(AllowCheckForUpdatesManual), AllowCheckForUpdates);
|
||||
public static bool AllowCheckForUpdatesManual { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies whether a question about checking for updates is displayed at startup.
|
||||
/// </summary>
|
||||
public static bool AllowPromptForUpdatesPreference { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Update, nameof(AllowPromptForUpdatesPreference), AllowCheckForUpdates);
|
||||
public static bool AllowPromptForUpdatesPreference { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
#region general credential registry settings
|
||||
|
||||
/// <summary>
|
||||
/// Setting that indicates whether exporting passwords is allowed.
|
||||
/// </summary>
|
||||
public static bool AllowExportPasswords { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Credential, nameof(AllowExportPasswords), true);
|
||||
public static bool AllowExportPasswords { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting that indicates whether exporting usernames is allowed.
|
||||
/// </summary>
|
||||
public static bool AllowExportUsernames { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Credential, nameof(AllowExportUsernames), true);
|
||||
public static bool AllowExportUsernames { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting that indicates whether saving passwords is allowed.
|
||||
/// Setting that indicates whether saving passwords in connections is allowed.
|
||||
/// </summary>
|
||||
public static bool AllowSavePasswords { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Credential, nameof(AllowSavePasswords), true);
|
||||
public static bool AllowSavePasswords { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting that indicates whether saving usernames is allowed.
|
||||
/// Setting that indicates whether saving in connections usernames is allowed.
|
||||
/// </summary>
|
||||
public static bool AllowSaveUsernames { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Credential, nameof(AllowSaveUsernames), true);
|
||||
public static bool AllowSaveUsernames { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Setting that indicates whether modifying credential settings is allowed.
|
||||
/// </summary>
|
||||
public static bool AllowModifyCredentialSettings { get; } = _WindowsRegistry.GetBoolValue(_Hive, __Credential, nameof(AllowModifyCredentialSettings), true);
|
||||
#endregion
|
||||
|
||||
static CommonRegistrySettings()
|
||||
{
|
||||
IRegistry regValueUtility = new WinRegistry();
|
||||
RegistryHive hive = WindowsRegistryInfo.Hive;
|
||||
|
||||
#region update registry settings setup
|
||||
|
||||
string updateSubkey = WindowsRegistryInfo.Update;
|
||||
|
||||
AllowCheckForUpdates = regValueUtility.GetBoolValue(hive, updateSubkey, nameof(AllowCheckForUpdates), true);
|
||||
AllowCheckForUpdatesAutomatical = regValueUtility.GetBoolValue(hive, updateSubkey, nameof(AllowCheckForUpdatesAutomatical), AllowCheckForUpdates);
|
||||
AllowCheckForUpdatesManual = regValueUtility.GetBoolValue(hive, updateSubkey, nameof(AllowCheckForUpdatesManual), AllowCheckForUpdates);
|
||||
AllowPromptForUpdatesPreference = regValueUtility.GetBoolValue(hive, updateSubkey, nameof(AllowPromptForUpdatesPreference), AllowCheckForUpdates);
|
||||
|
||||
#endregion
|
||||
|
||||
#region credential registry settings setup
|
||||
|
||||
string credentialSubkey = WindowsRegistryInfo.Credential;
|
||||
|
||||
AllowExportPasswords = regValueUtility.GetBoolValue(hive, credentialSubkey, nameof(AllowExportPasswords), true);
|
||||
AllowExportUsernames = regValueUtility.GetBoolValue(hive, credentialSubkey, nameof(AllowExportUsernames), true);
|
||||
AllowSavePasswords = regValueUtility.GetBoolValue(hive, credentialSubkey, nameof(AllowSavePasswords), true);
|
||||
AllowSaveUsernames = regValueUtility.GetBoolValue(hive, credentialSubkey, nameof(AllowSaveUsernames), true);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,16 +9,22 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// Static utility class that provides access to and management of registry settings on the local machine.
|
||||
/// It abstracts complex registry operations and centralizes the handling of various registry keys.
|
||||
/// Benefits: Simplified code, enhances maintainability, and ensures consistency. #ReadOnly
|
||||
public sealed partial class OptRegistryCredentialsPage : WindowsRegistryAdvanced
|
||||
public sealed partial class OptRegistryCredentialsPage
|
||||
{
|
||||
#region option page credential registry settings
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether modifying credential page settings is enabled.
|
||||
/// </summary>
|
||||
public bool CredentialPageEnabled { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the radio button is set to none, windows or custom on the credentials page.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// When set to noinfo or windows, WindowsCredentials and CustomCredentials are not evaluated and disabled.
|
||||
/// </remarks>
|
||||
public WindowsRegistryKeyString UseCredentials { get; }
|
||||
public WinRegistryEntry<string> UseCredentials { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the user set via API as the default username.
|
||||
@@ -26,7 +32,7 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// <remarks>
|
||||
/// Only avaiable if UseCredentials is set to custom!
|
||||
/// </remarks>
|
||||
public WindowsRegistryKeyString UserViaAPIDefault { get; }
|
||||
public WinRegistryEntry<string> UserViaAPIDefault { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the default username.
|
||||
@@ -34,7 +40,7 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// <remarks>
|
||||
/// Only avaiable if UseCredentials is set to custom!
|
||||
/// </remarks>
|
||||
public WindowsRegistryKeyString DefaultUsername { get; }
|
||||
public WinRegistryEntry<string> DefaultUsername { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the default password.
|
||||
@@ -42,7 +48,7 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// <remarks>
|
||||
/// Only avaiable if UseCredentials is set to custom!
|
||||
/// </remarks>
|
||||
//public WindowsRegistryKeyString DefaultPassword { get; }
|
||||
public WinRegistryEntry<string> DefaultPassword { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the default domain.
|
||||
@@ -50,28 +56,27 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// <remarks>
|
||||
/// Only avaiable if UseCredentials is set to custom!
|
||||
/// </remarks>
|
||||
public WindowsRegistryKeyString DefaultDomain { get; }
|
||||
public WinRegistryEntry<string> DefaultDomain { get; }
|
||||
|
||||
#endregion
|
||||
|
||||
public OptRegistryCredentialsPage()
|
||||
{
|
||||
IRegistry regValueUtility = new WinRegistry();
|
||||
RegistryHive hive = WindowsRegistryInfo.Hive;
|
||||
string subKey = WindowsRegistryInfo.CredentialOptionsSubkey;
|
||||
string subKey = WindowsRegistryInfo.CredentialOptions;
|
||||
|
||||
UseCredentials = GetStringValidated(hive, subKey, nameof(UseCredentials),
|
||||
CredentialPageEnabled = regValueUtility.GetBoolValue(hive, subKey, nameof(CredentialPageEnabled), true);
|
||||
UseCredentials = new WinRegistryEntry<string>(hive, subKey, nameof(UseCredentials)).SetValidation(
|
||||
new string[] {
|
||||
"noinfo",
|
||||
"windows",
|
||||
"custom"
|
||||
}, true
|
||||
);
|
||||
|
||||
UserViaAPIDefault = GetString(hive, subKey, nameof(UserViaAPIDefault), null);
|
||||
DefaultUsername = GetString(hive, subKey, nameof(DefaultUsername), null);
|
||||
//Currently not supported, but needed for configuration...
|
||||
//DefaultPassword = GetPassword(hive, subKey, nameof(DefaultPassword));
|
||||
|
||||
DefaultDomain = GetString(hive, subKey, nameof(DefaultDomain), null);
|
||||
}).Read();
|
||||
UserViaAPIDefault = new WinRegistryEntry<string>(hive, subKey, nameof(UserViaAPIDefault)).Read();
|
||||
DefaultUsername = new WinRegistryEntry<string>(hive, subKey, nameof(DefaultUsername)).Read();
|
||||
DefaultPassword = new WinRegistryEntry<string>(hive, subKey, nameof(DefaultPassword)).Read();
|
||||
DefaultDomain = new WinRegistryEntry<string>(hive, subKey, nameof(DefaultDomain)).Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -9,12 +9,12 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// Static utility class that provides access to and management of registry settings on the local machine.
|
||||
/// It abstracts complex registry operations and centralizes the handling of various registry keys.
|
||||
/// Benefits: Simplified code, enhances maintainability, and ensures consistency. #ReadOnly
|
||||
public sealed partial class OptRegistryUpdatesPage : WindowsRegistryAdvanced
|
||||
public sealed partial class OptRegistryUpdatesPage
|
||||
{
|
||||
/// <summary>
|
||||
/// Specifies the number of days between update checks.
|
||||
/// </summary>
|
||||
public WindowsRegistryKeyInteger CheckForUpdatesFrequencyDays { get; }
|
||||
public WinRegistryEntry<int> CheckForUpdatesFrequencyDays { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the update channel for updates.
|
||||
@@ -22,62 +22,58 @@ namespace mRemoteNG.Config.Settings.Registry
|
||||
/// <remarks>
|
||||
/// The update channel should be one of the predefined values: Stable, Preview, Nightly.
|
||||
/// </remarks>
|
||||
public WindowsRegistryKeyString UpdateChannel { get; }
|
||||
public WinRegistryEntry<string> UpdateChannel { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether proxy usage for updates is enabled.
|
||||
/// </summary>
|
||||
public WindowsRegistryKeyBoolean UseProxyForUpdates { get; }
|
||||
public WinRegistryEntry<bool> UseProxyForUpdates { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the proxy address for updates.
|
||||
/// </summary>
|
||||
public WindowsRegistryKeyString ProxyAddress { get; }
|
||||
public WinRegistryEntry<string> ProxyAddress { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the proxy port for updates.
|
||||
/// </summary>
|
||||
public WindowsRegistryKeyInteger ProxyPort { get; }
|
||||
public WinRegistryEntry<int> ProxyPort { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether proxy authentication is enabled.
|
||||
/// </summary>
|
||||
public WindowsRegistryKeyBoolean UseProxyAuthentication { get; }
|
||||
public WinRegistryEntry<bool> UseProxyAuthentication { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the authentication username for the proxy.
|
||||
/// </summary>
|
||||
public WindowsRegistryKeyString ProxyAuthUser { get; }
|
||||
public WinRegistryEntry<string> ProxyAuthUser { get; }
|
||||
|
||||
/// <summary>
|
||||
/// Specifies the authentication password for the proxy.
|
||||
/// </summary>
|
||||
//public string ProxyAuthPass { get; }
|
||||
public WinRegistryEntry<string> ProxyAuthPass { get; }
|
||||
|
||||
public OptRegistryUpdatesPage()
|
||||
{
|
||||
RegistryHive hive = WindowsRegistryInfo.Hive;
|
||||
string subKey = WindowsRegistryInfo.UpdateOptionsSubkey;
|
||||
string subKey = WindowsRegistryInfo.UpdateOptions;
|
||||
|
||||
CheckForUpdatesFrequencyDays = GetInteger(hive, subKey, nameof(CheckForUpdatesFrequencyDays));
|
||||
|
||||
UpdateChannel = GetStringValidated(hive, subKey, nameof(UpdateChannel),
|
||||
new string[] {
|
||||
CheckForUpdatesFrequencyDays = new WinRegistryEntry<int>(hive, subKey, nameof(CheckForUpdatesFrequencyDays)).Read();
|
||||
UpdateChannel = new WinRegistryEntry<string>(hive, subKey, nameof(UpdateChannel))
|
||||
.SetValidation(new string[] {
|
||||
UpdateChannelInfo.STABLE,
|
||||
UpdateChannelInfo.PREVIEW,
|
||||
UpdateChannelInfo.NIGHTLY
|
||||
}
|
||||
,true
|
||||
);
|
||||
}).Read();
|
||||
|
||||
UseProxyForUpdates = GetBoolean(hive, subKey, nameof(UseProxyForUpdates));
|
||||
ProxyAddress = GetString(hive, subKey, nameof(ProxyAddress), null);
|
||||
ProxyPort = GetInteger(hive, subKey, nameof(ProxyPort));
|
||||
UseProxyForUpdates = new WinRegistryEntry<bool>(hive, subKey, nameof(UseProxyForUpdates)).Read();
|
||||
ProxyAddress = new WinRegistryEntry<string>(hive, subKey, nameof(ProxyAddress)).Read();
|
||||
ProxyPort = new WinRegistryEntry<int>(hive, subKey, nameof(ProxyPort)).Read();
|
||||
|
||||
UseProxyAuthentication = GetBoolean(hive, subKey, nameof(UseProxyAuthentication));
|
||||
ProxyAuthUser = GetString(hive, subKey, nameof(ProxyAuthUser), null);
|
||||
//Currently not supported:
|
||||
//ProxyAuthPass = GetPassword(Hive, _SubKey, nameof(ProxyAuthPass));
|
||||
UseProxyAuthentication = new WinRegistryEntry<bool>(hive, subKey, nameof(UseProxyAuthentication)).Read();
|
||||
ProxyAuthUser = new WinRegistryEntry<string>(hive, subKey, nameof(ProxyAuthUser)).Read();
|
||||
ProxyAuthPass = new WinRegistryEntry<string>(hive, subKey, nameof(ProxyAuthPass)).Read();
|
||||
}
|
||||
}
|
||||
}
|
||||
4
mRemoteNG/Language/Language.Designer.cs
generated
4
mRemoteNG/Language/Language.Designer.cs
generated
@@ -3399,9 +3399,9 @@ namespace mRemoteNG.Resources.Language {
|
||||
/// <summary>
|
||||
/// Looks up a localized string similar to *Some settings are determined by your company. For further information, please contact your administrator.
|
||||
/// </summary>
|
||||
internal static string OptionsAdminInfo {
|
||||
internal static string OptionsCompanyPolicyMessage {
|
||||
get {
|
||||
return ResourceManager.GetString("OptionsAdminInfo", resourceCulture);
|
||||
return ResourceManager.GetString("OptionsCompanyPolicyMessage", resourceCulture);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -2047,7 +2047,7 @@ Nightly umfasst Alphas, Betas und Release Candidates.</value>
|
||||
<value>Maximale Anmeldeversuche erreicht. Verbindung erneut initiieren.</value>
|
||||
<comment>C# to Powershell transfer issue with encoding possible</comment>
|
||||
</data>
|
||||
<data name="OptionsAdminInfo" xml:space="preserve">
|
||||
<data name="OptionsCompanyPolicyMessage" xml:space="preserve">
|
||||
<value>*Einige Einstellungen werden von Ihrem Unternehmen festgelegt. Für weitere Informationen wenden Sie sich an Ihren Systemadministrator.</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -2292,7 +2292,7 @@ Nightly Channel includes Alphas, Betas & Release Candidates.</value>
|
||||
<data name="ECPClickstudiosPasswordstate" xml:space="preserve">
|
||||
<value>Clickstudios Passwordstate</value>
|
||||
</data>
|
||||
<data name="ECPNone" xml:space="preserve">
|
||||
<data name="ECPNone" xml:space="preserve">
|
||||
<value>None</value>
|
||||
</data>
|
||||
<data name="EAPAmazonWebServices" xml:space="preserve">
|
||||
@@ -2365,7 +2365,7 @@ Nightly Channel includes Alphas, Betas & Release Candidates.</value>
|
||||
<data name="FilterSecureCRT" xml:space="preserve">
|
||||
<value>SecureCRT (*.xml)</value>
|
||||
</data>
|
||||
<data name="OptionsAdminInfo" xml:space="preserve">
|
||||
<data name="OptionsCompanyPolicyMessage" xml:space="preserve">
|
||||
<value>*Some settings are determined by your company. For further information, please contact your administrator</value>
|
||||
</data>
|
||||
</root>
|
||||
@@ -6,39 +6,98 @@ using System.Runtime.Versioning;
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Interface for the Registry class providing methods for interacting with the Windows Registry.
|
||||
/// </summary>
|
||||
public interface IRegistry
|
||||
{
|
||||
#region registry reader
|
||||
#region Registry Reader
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of subkeys under the specified registry hive and path.
|
||||
/// </summary>
|
||||
string[] GetSubKeyNames(RegistryHive hive, string path);
|
||||
string GetPropertyValue(WindowsRegistryKey key);
|
||||
string GetPropertyValue(RegistryHive hive, string path, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
string GetValue(RegistryHive hive, string path, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
string GetStringValue(RegistryHive hive, string path, string name, string defaultValue = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the boolean value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
bool GetBoolValue(RegistryHive hive, string path, string propertyName, bool defaultValue = false);
|
||||
int GetDwordValue(RegistryHive hive, string path, string propertyName, int defaultValue = 0);
|
||||
|
||||
WindowsRegistryKey GetWindowsRegistryKey(RegistryHive hive, string path, string name);
|
||||
WindowsRegistryKey GetWindowsRegistryKey(WindowsRegistryKey key);
|
||||
/// <summary>
|
||||
/// Gets the DWORD value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
int GetIntegerValue(RegistryHive hive, string path, string propertyName, int defaultValue = -1);
|
||||
|
||||
List<WindowsRegistryKey> GetRegistryEntries(RegistryHive hive, string path);
|
||||
List<WindowsRegistryKey> GetRegistryEntryiesRecursive(RegistryHive hive, string path);
|
||||
/// <summary>
|
||||
/// Retrieves a specific registry entry of type string from the Windows Registry.
|
||||
/// </summary>
|
||||
WinRegistryEntry<string> GetEntry(RegistryHive hive, string path, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of string-type registry entries from the Windows Registry under the specified path.
|
||||
/// </summary>
|
||||
List<WinRegistryEntry<string>> GetEntries(RegistryHive hive, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of string-type registry entries from the Windows Registry under the specified path and its subkeys recursively.
|
||||
/// </summary>
|
||||
List<WinRegistryEntry<string>> GetEntriesRecursive(RegistryHive hive, string path);
|
||||
|
||||
#endregion
|
||||
|
||||
#region registry writer
|
||||
void SetRegistryValue(WindowsRegistryKey key);
|
||||
void SetRegistryValue(RegistryHive hive, string path, string name, object value, RegistryValueKind valueKind);
|
||||
void DeleteRegistryKey(RegistryHive hive, string path, bool ignoreNotFound = false);
|
||||
#region Registry Writer
|
||||
|
||||
/// <summary>
|
||||
/// Sets the value of a registry entry.
|
||||
/// </summary>
|
||||
void SetValue(RegistryHive hive, string path, string name, object value, RegistryValueKind valueKind);
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new registry key.
|
||||
/// </summary>
|
||||
void CreateKey(RegistryHive hive, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a registry value.
|
||||
/// </summary>
|
||||
void DeleteRegistryValue(RegistryHive hive, string path, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a registry key and all its subkeys and values.
|
||||
/// </summary>
|
||||
void DeleteTree(RegistryHive hive, string path);
|
||||
|
||||
#endregion
|
||||
|
||||
#region registry tools
|
||||
#region Registry Tools
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string representation of a registry hive to the corresponding RegistryHive enum value.
|
||||
/// </summary>
|
||||
RegistryHive ConvertStringToRegistryHive(string hiveString);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string representation of a registry value kind to the corresponding RegistryValueKind enum value.
|
||||
/// </summary>
|
||||
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a .NET type to the corresponding RegistryValueKind enum value.
|
||||
/// </summary>
|
||||
RegistryValueKind ConvertTypeToRegistryValueKind(Type valueType);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a RegistryValueKind enum value to the corresponding .NET type.
|
||||
/// </summary>
|
||||
Type ConvertRegistryValueKindToType(RegistryValueKind valueKind);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,55 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Interface for the RegistryWorker class providing functionality to interact with the Windows Registry to retrieve registry settings.
|
||||
/// </summary>
|
||||
public interface IRegistryAdvanced
|
||||
{
|
||||
#region WindowsRegistry reader
|
||||
string[] GetSubKeyNames(RegistryHive hive, string path);
|
||||
string GetPropertyValue(WindowsRegistryKey key);
|
||||
string GetPropertyValue(RegistryHive hive, string path, string name);
|
||||
|
||||
bool GetBoolValue(RegistryHive hive, string path, string propertyName, bool defaultValue = false);
|
||||
int GetDwordValue(RegistryHive hive, string path, string propertyName, int defaultValue = 0);
|
||||
|
||||
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 WindowsRegistry writer
|
||||
void SetRegistryValue(WindowsRegistryKey key);
|
||||
void SetRegistryValue(RegistryHive hive, string path, string name, object value, RegistryValueKind valueKind);
|
||||
void DeleteRegistryKey(RegistryHive hive, string path, bool ignoreNotFound = false);
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry tools
|
||||
RegistryHive ConvertStringToRegistryHive(string hiveString);
|
||||
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
|
||||
RegistryValueKind ConvertTypeToRegistryValueKind(Type valueType);
|
||||
Type ConvertRegistryValueKindToType(RegistryValueKind valueKind);
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryAdvanced GetInteger
|
||||
WindowsRegistryKeyInteger GetInteger(RegistryHive hive, string path, string propertyName, int? defaultValue = null);
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryAdvanced GetString
|
||||
WindowsRegistryKeyString GetString(RegistryHive hive, string path, string propertyName, string defaultValue = null);
|
||||
WindowsRegistryKeyString GetStringValidated(RegistryHive hive, string path, string propertyName, string[] allowedValues, bool caseSensitive = false, string defaultValue = null);
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryAdvanced GetBoolean
|
||||
WindowsRegistryKeyBoolean GetBoolean(RegistryHive hive, string path, string propertyName, bool? defaultValue = null);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Interface for the RegistryWorker class providing functionality to interact with the Windows Registry to retrieve registry settings.
|
||||
/// </summary>
|
||||
public interface IRegistryAdvancedRead
|
||||
{
|
||||
#region WindowsRegistry reader
|
||||
string[] GetSubKeyNames(RegistryHive hive, string path);
|
||||
string GetPropertyValue(WindowsRegistryKey key);
|
||||
string GetPropertyValue(RegistryHive hive, string path, string name);
|
||||
|
||||
bool GetBoolValue(RegistryHive hive, string path, string propertyName, bool defaultValue = false);
|
||||
int GetDwordValue(RegistryHive hive, string path, string propertyName, int defaultValue = 0);
|
||||
|
||||
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 WindowsRegistry tools
|
||||
RegistryHive ConvertStringToRegistryHive(string hiveString);
|
||||
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
|
||||
RegistryValueKind ConvertTypeToRegistryValueKind(Type valueType);
|
||||
Type ConvertRegistryValueKindToType(RegistryValueKind valueKind);
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryAdvanced GetInteger
|
||||
WindowsRegistryKeyInteger GetInteger(RegistryHive hive, string path, string propertyName, int? defaultValue = null);
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryAdvanced GetString
|
||||
WindowsRegistryKeyString GetString(RegistryHive hive, string path, string propertyName, string defaultValue = null);
|
||||
WindowsRegistryKeyString GetStringValidated(RegistryHive hive, string path, string propertyName, string[] allowedValues, bool caseSensitive = false, string defaultValue = null);
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryAdvanced GetBoolean
|
||||
WindowsRegistryKeyBoolean GetBoolean(RegistryHive hive, string path, string propertyName, bool? defaultValue = null);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -6,31 +6,74 @@ using System.Runtime.Versioning;
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Interface for the Registry class providing methods for interacting with read actions in the Windows Registry.
|
||||
/// </summary>
|
||||
public interface IRegistryRead
|
||||
{
|
||||
#region registry reader
|
||||
#region Registry Reader
|
||||
|
||||
/// <summary>
|
||||
/// Gets the names of subkeys under the specified registry hive and path.
|
||||
/// </summary>
|
||||
string[] GetSubKeyNames(RegistryHive hive, string path);
|
||||
string GetPropertyValue(WindowsRegistryKey key);
|
||||
string GetPropertyValue(RegistryHive hive, string path, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
string GetValue(RegistryHive hive, string path, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the string value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
string GetStringValue(RegistryHive hive, string path, string name, string defaultValue = null);
|
||||
|
||||
/// <summary>
|
||||
/// Gets the boolean value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
bool GetBoolValue(RegistryHive hive, string path, string propertyName, bool defaultValue = false);
|
||||
int GetDwordValue(RegistryHive hive, string path, string propertyName, int defaultValue = 0);
|
||||
|
||||
WindowsRegistryKey GetWindowsRegistryKey(RegistryHive hive, string path, string name);
|
||||
WindowsRegistryKey GetWindowsRegistryKey(WindowsRegistryKey key);
|
||||
/// <summary>
|
||||
/// Gets the DWORD value of a registry entry specified by its name.
|
||||
/// </summary>
|
||||
int GetIntegerValue(RegistryHive hive, string path, string propertyName, int defaultValue = -1);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a specific registry entry of type string from the Windows Registry.
|
||||
/// </summary>
|
||||
WinRegistryEntry<string> GetEntry(RegistryHive hive, string path, string name);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of string-type registry entries from the Windows Registry under the specified path.
|
||||
/// </summary>
|
||||
List<WinRegistryEntry<string>> GetEntries(RegistryHive hive, string path);
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of string-type registry entries from the Windows Registry under the specified path and its subkeys recursively.
|
||||
/// </summary>
|
||||
List<WinRegistryEntry<string>> GetEntriesRecursive(RegistryHive hive, string path);
|
||||
|
||||
List<WindowsRegistryKey> GetRegistryEntries(RegistryHive hive, string path);
|
||||
List<WindowsRegistryKey> GetRegistryEntryiesRecursive(RegistryHive hive, string path);
|
||||
#endregion
|
||||
|
||||
#region registry tools
|
||||
#region Registry Tools
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string representation of a registry hive to the corresponding RegistryHive enum value.
|
||||
/// </summary>
|
||||
RegistryHive ConvertStringToRegistryHive(string hiveString);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string representation of a registry value kind to the corresponding RegistryValueKind enum value.
|
||||
/// </summary>
|
||||
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a .NET type to the corresponding RegistryValueKind enum value.
|
||||
/// </summary>
|
||||
RegistryValueKind ConvertTypeToRegistryValueKind(Type valueType);
|
||||
|
||||
/// <summary>
|
||||
/// Converts a RegistryValueKind enum value to the corresponding .NET type.
|
||||
/// </summary>
|
||||
Type ConvertRegistryValueKindToType(RegistryValueKind valueKind);
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,26 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Interface for the Registry class providing methods for interacting with write actions in the Windows Registry.
|
||||
/// </summary>
|
||||
public interface IRegistryWrite
|
||||
{
|
||||
#region registry writer
|
||||
void SetRegistryValue(WindowsRegistryKey key);
|
||||
void SetRegistryValue(RegistryHive hive, string path, string name, object value, RegistryValueKind valueKind);
|
||||
|
||||
#endregion
|
||||
|
||||
#region registry tools
|
||||
RegistryHive ConvertStringToRegistryHive(string hiveString);
|
||||
RegistryValueKind ConvertStringToRegistryValueKind(string valueType);
|
||||
RegistryValueKind ConvertTypeToRegistryValueKind(Type valueType);
|
||||
Type ConvertRegistryValueKindToType(RegistryValueKind valueKind);
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
491
mRemoteNG/Tools/WindowsRegistry/WinRegistry.cs
Normal file
491
mRemoteNG/Tools/WindowsRegistry/WinRegistry.cs
Normal file
@@ -0,0 +1,491 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Provides functionality to interact with the Windows Registry, including reading, writing, and managing registry entries.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class encapsulates common functionality for working with the Windows Registry. It offers methods to open registry keys, create subkeys, and read or write values.
|
||||
/// The class serves as a base for specialized registry entry classes, centralizing registry operations and validation checks.
|
||||
/// Users can create instances of this class to perform various registry operations, such as retrieving subkey names, reading values of different types, creating keys, and deleting registry entries or keys.
|
||||
/// Additionally, the class includes methods for converting between different registry value types and handling custom validation rules.
|
||||
///
|
||||
/// License:
|
||||
/// This class is licensed under MIT License.
|
||||
/// </remarks>
|
||||
public class WinRegistry : IRegistry, IRegistryRead
|
||||
{
|
||||
#region Public Read Method: GetSubKeyNames
|
||||
|
||||
/// <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)
|
||||
{
|
||||
ThrowIfHiveInvalid(Hive);
|
||||
ThrowIfPathInvalid(Path);
|
||||
|
||||
using var key = RegistryKey.OpenBaseKey(Hive, RegistryView.Default).OpenSubKey(Path);
|
||||
if (key != null)
|
||||
return key.GetSubKeyNames();
|
||||
else
|
||||
return Array.Empty<string>();
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Read Value Method
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the data value associated with the specified registry key and value name.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive.</param>
|
||||
/// <param name="Path">The registry key path.</param>
|
||||
/// <param name="Name">The name of the value. Null or Empty to get default.</param>
|
||||
/// <returns>The value data as a string, or null if the value is not found.</returns>
|
||||
/// <exception cref = "ArgumentException" > Thrown when the specified registry hive, path or name is invalid</exception>
|
||||
public string GetValue(RegistryHive Hive, string Path, string Name)
|
||||
{
|
||||
ThrowIfHiveInvalid(Hive);
|
||||
ThrowIfPathInvalid(Path);
|
||||
|
||||
using var key = RegistryKey.OpenBaseKey(Hive, RegistryView.Default).OpenSubKey(Path);
|
||||
if (key == null)
|
||||
return null;
|
||||
|
||||
// Ensure name is null when null or empty to get defaults value
|
||||
if (string.IsNullOrEmpty(Name))
|
||||
Name = null;
|
||||
|
||||
return key.GetValue(Name)?.ToString();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the data value associated with the specified registry key and uses the default value if the value name is not specified.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive.</param>
|
||||
/// <param name="Path">The registry key path.</param>
|
||||
/// <returns>The value data as a string, or null if the value is not found.</returns>
|
||||
public string GetDefaultValue(RegistryHive Hive, string Path)
|
||||
{
|
||||
return GetValue(Hive, Path, null);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the string value from the specified REG_SZ registry key.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive.</param>
|
||||
/// <param name="Path">The registry key path.</param>
|
||||
/// <param name="Name">The name of the value. Null or Empty to get default.</param>
|
||||
/// <param name="DefaultValue">The default value to return if the property is not found.</param>
|
||||
/// <returns>The value data as string, or the specified default value if the value is not found.</returns>
|
||||
public string GetStringValue(RegistryHive Hive, string Path, string Name, string DefaultValue = null)
|
||||
{
|
||||
string value = GetValue(Hive, Path, Name);
|
||||
return value ?? DefaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the bool value from from the specified REG_SZ or REG_DWORD registry key.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive.</param>
|
||||
/// <param name="Path">The registry key path.</param>
|
||||
/// <param name="Name">The name of the value.</param>
|
||||
/// <param name="DefaultValue">The default value to return if the property is not found or cannot be parsed. (Default = false)</param>
|
||||
/// <returns>The value data as bool, parsed from its REG_SZ or REG_DWORD representation if possible, or the specified default value if the value is not found or cannot be parsed.</returns>
|
||||
public bool GetBoolValue(RegistryHive Hive, string Path, string Name, bool DefaultValue = false)
|
||||
{
|
||||
string value = GetValue(Hive, Path, Name);
|
||||
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
if (int.TryParse(value, out int intValue))
|
||||
return intValue == 1;
|
||||
if (bool.TryParse(value, out bool boolValue))
|
||||
return boolValue;
|
||||
}
|
||||
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves the integer value from from the specified REG_DWORD registry key.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive.</param>
|
||||
/// <param name="Path">The registry key path.</param>
|
||||
/// <param name="Name">The name of the value.</param>
|
||||
/// <param name="DefaultValue">The default value to return if the property is not found or cannot be parsed. (Default = 0)</param>
|
||||
/// <returns>The value data as integer, parsed from its REG_DWORD representation if possible, or the specified default value if the value is not found or cannot be parsed.</returns>
|
||||
public int GetIntegerValue(RegistryHive Hive, string Path, string Name, int DefaultValue = 0)
|
||||
{
|
||||
string value = GetValue(Hive, Path, Name);
|
||||
|
||||
if (int.TryParse(value, out int intValue))
|
||||
return intValue;
|
||||
|
||||
return DefaultValue;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Read Tree Methods
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a windows registry entry 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 WinRegistryEntry<string> object representing the specified registry key and value.</returns>
|
||||
public WinRegistryEntry<string> GetEntry(RegistryHive hive, string path, string name)
|
||||
{
|
||||
return WinRegistryEntry<string>
|
||||
.New(hive, path, name)
|
||||
.Read();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a list of registry entries and their values under a given key path.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive.</param>
|
||||
/// <param name="path">The registry key path.</param>
|
||||
/// <returns>A list of WinRegistryEntry<string> objects, each representing a value within the specified registry key path.</returns>
|
||||
public List<WinRegistryEntry<string>> GetEntries(RegistryHive hive, string path)
|
||||
{
|
||||
using var key = RegistryKey.OpenBaseKey(hive, RegistryView.Default).OpenSubKey(path);
|
||||
if (key == null)
|
||||
return new List<WinRegistryEntry<string>>(); // Return an empty list when no key is found
|
||||
|
||||
return key.GetValueNames()
|
||||
.Select(name => WinRegistryEntry<string>.New(hive, path, name)
|
||||
.Read())
|
||||
.ToList();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Recursively retrieves registry entries under a given key path and its subkeys.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive.</param>
|
||||
/// <param name="path">The registry key path.</param>
|
||||
/// <returns>A list of WinRegistryEntry<string> objects, each representing a value within the specified registry key path.</returns>
|
||||
public List<WinRegistryEntry<string>> GetEntriesRecursive(RegistryHive hive, string path)
|
||||
{
|
||||
List<WinRegistryEntry<string>> list = new();
|
||||
using (var baseKey = RegistryKey.OpenBaseKey(hive, RegistryView.Default))
|
||||
using (var key = baseKey.OpenSubKey(path))
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
foreach (string subPathName in key.GetSubKeyNames())
|
||||
{
|
||||
string subKey = $"{path}\\{subPathName}";
|
||||
list.AddRange(GetEntriesRecursive(hive, subKey));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
list.AddRange(GetEntries(hive, path));
|
||||
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 registry key path.</param>
|
||||
/// <param name="Name">The name of the value.</param>
|
||||
/// <param name="Value">The value to set for the property.</param>
|
||||
/// <param name="ValueKind">The data type of the value to set.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown when an error occurs while writing to the Windows Registry key.</exception>
|
||||
public void SetValue(RegistryHive Hive, string Path, string Name, object Value, RegistryValueKind ValueKind)
|
||||
{
|
||||
ThrowIfHiveInvalid(Hive);
|
||||
ThrowIfPathInvalid(Path);
|
||||
|
||||
string name = string.IsNullOrEmpty(Name) ? null : Name;
|
||||
RegistryValueKind valueKind = string.IsNullOrEmpty(Name) ? RegistryValueKind.String : ValueKind;
|
||||
|
||||
ThrowIfValueKindInvalid(valueKind);
|
||||
|
||||
try
|
||||
{
|
||||
using RegistryKey baseKey = RegistryKey.OpenBaseKey(Hive, RegistryView.Default);
|
||||
using RegistryKey registryKey = baseKey.CreateSubKey(Path, true);
|
||||
|
||||
registryKey.SetValue(name, Value, valueKind);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Error writing to the Windows Registry.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the default value of a registry key to the specified string value.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive.</param>
|
||||
/// <param name="Path">The registry key path.</param>
|
||||
/// <param name="Value">The value to set for the default property.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when the specified registry hive or path is invalid.</exception>
|
||||
/// <exception cref="InvalidOperationException">Thrown when an error occurs while writing to the Windows Registry key.</exception>
|
||||
public void SetDefaultValue(RegistryHive Hive, string Path, string Value)
|
||||
{
|
||||
SetValue(Hive, Path, null, Value, RegistryValueKind.String);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a registry key at the specified location.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive to create the key under.</param>
|
||||
/// <param name="Path">The path of the registry key to create.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when the specified registry hive or path is invalid</exception>
|
||||
/// <exception cref="InvalidOperationException">Thrown when an error occurs while creating the Windows Registry key.</exception>
|
||||
public void CreateKey(RegistryHive Hive, string Path)
|
||||
{
|
||||
ThrowIfHiveInvalid(Hive);
|
||||
ThrowIfPathInvalid(Path);
|
||||
|
||||
try
|
||||
{
|
||||
using RegistryKey baseKey = RegistryKey.OpenBaseKey(Hive, RegistryView.Default);
|
||||
baseKey.CreateSubKey(Path);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Error creating the Windows Registry key.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Delete Methods
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a registry value under the specified registry key.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive to open.</param>
|
||||
/// <param name="Path">The path of the registry key where the value exists.</param>
|
||||
/// <param name="Name">The name of the value to delete.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when the specified registry hive, path or name is invalid</exception>
|
||||
/// <exception cref="UnauthorizedAccessException">Thrown when the user does not have the necessary permissions to delete the registry value.</exception>
|
||||
/// <exception cref="SecurityException">Thrown when the user does not have the necessary permissions to delete the registry value due to security restrictions.</exception>
|
||||
public void DeleteRegistryValue(RegistryHive Hive, string Path, string Name)
|
||||
{
|
||||
ThrowIfHiveInvalid(Hive);
|
||||
ThrowIfPathInvalid(Path);
|
||||
ThrowIfNameInvalid(Name);
|
||||
try
|
||||
{
|
||||
using RegistryKey baseKey = RegistryKey.OpenBaseKey(Hive, RegistryView.Default);
|
||||
using RegistryKey key = baseKey.OpenSubKey(Path, true);
|
||||
key?.DeleteValue(Name, true);
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
throw new SecurityException("Insufficient permissions to delete the registry key or value.", ex);
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
throw new UnauthorizedAccessException("Insufficient permissions to delete the registry key or value due to security restrictions.", ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("An error occurred while deleting the registry key or value.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a registry key and its subkeys.
|
||||
/// </summary>
|
||||
/// <param name="Hive">The registry hive to open.</param>
|
||||
/// <param name="Path">The path of the registry key to delete.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when the specified registry hive or path is invalid</exception>
|
||||
/// <exception cref="UnauthorizedAccessException">Thrown when the user does not have the necessary permissions to delete the registry key.</exception>
|
||||
/// <exception cref="SecurityException">Thrown when the user does not have the necessary permissions to delete the registry key due to security restrictions.</exception>
|
||||
public void DeleteTree(RegistryHive Hive, string Path)
|
||||
{
|
||||
ThrowIfHiveInvalid(Hive);
|
||||
ThrowIfPathInvalid(Path);
|
||||
try
|
||||
{
|
||||
using RegistryKey baseKey = RegistryKey.OpenBaseKey(Hive, RegistryView.Default);
|
||||
baseKey?.DeleteSubKeyTree(Path, true);
|
||||
}
|
||||
catch (SecurityException ex)
|
||||
{
|
||||
throw new SecurityException("Insufficient permissions to delete the registry key or value.", ex);
|
||||
}
|
||||
catch (UnauthorizedAccessException ex)
|
||||
{
|
||||
throw new UnauthorizedAccessException("Insufficient permissions to delete the registry key or value due to security restrictions.", ex);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new Exception("An error occurred while deleting the registry key or value.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Converter Methods
|
||||
|
||||
/*******************************************************
|
||||
*
|
||||
* Converter 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)
|
||||
{
|
||||
if (string.IsNullOrEmpty(HiveString))
|
||||
throw new ArgumentNullException(nameof(HiveString), "The registry hive string cannot be null or empty. Please provide a valid registry hive string.");
|
||||
|
||||
return HiveString.ToLower() switch
|
||||
{
|
||||
"hkcr" or "hkey_classes_root" or "classesroot" => RegistryHive.ClassesRoot,
|
||||
"hkcu" or "hkey_current_user" or "currentuser" => RegistryHive.CurrentUser,
|
||||
"hklm" or "hkey_local_machine" or "localmachine" => RegistryHive.LocalMachine,
|
||||
"hku" or "hkey_users" or "users" => RegistryHive.Users,
|
||||
"hkcc" or "hkey_current_config" or "currentconfig" => RegistryHive.CurrentConfig,
|
||||
_ => 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)
|
||||
{
|
||||
if (string.IsNullOrEmpty(ValueType))
|
||||
throw new ArgumentNullException(nameof(ValueType), "The registry value type string cannot be null or empty. Please provide a valid registry value type string.");
|
||||
|
||||
return ValueType.ToLower() switch
|
||||
{
|
||||
"string" or "reg_sz" => RegistryValueKind.String,
|
||||
"dword" or "reg_dword" => RegistryValueKind.DWord,
|
||||
"binary" or "reg_binary" => RegistryValueKind.Binary,
|
||||
"qword" or "reg_qword" => RegistryValueKind.QWord,
|
||||
"multistring" or "reg_multi_sz" => RegistryValueKind.MultiString,
|
||||
"expandstring" or "reg_expand_sz" => RegistryValueKind.ExpandString,
|
||||
_ => throw new ArgumentException("Invalid RegistryValueKind string representation.", nameof(ValueType)),
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
/// <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>
|
||||
public RegistryValueKind ConvertTypeToRegistryValueKind(Type ValueType)
|
||||
{
|
||||
if (ValueType == null)
|
||||
throw new ArgumentNullException(nameof(ValueType), "The value type argument cannot be null.");
|
||||
|
||||
return Type.GetTypeCode(ValueType) switch
|
||||
{
|
||||
TypeCode.String => RegistryValueKind.String,
|
||||
TypeCode.Int32 => RegistryValueKind.DWord,
|
||||
TypeCode.Int64 => RegistryValueKind.QWord,
|
||||
TypeCode.Boolean => RegistryValueKind.DWord,
|
||||
TypeCode.Byte => RegistryValueKind.Binary,
|
||||
/*
|
||||
TypeCode.Single => RegistryValueKind.String,
|
||||
TypeCode.Double => RegistryValueKind.String;
|
||||
TypeCode.DateTime => RegistryValueKind.String;
|
||||
TypeCode.Char => RegistryValueKind.String;
|
||||
TypeCode.Decimal => RegistryValueKind.String;
|
||||
*/
|
||||
_ => 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>
|
||||
public Type ConvertRegistryValueKindToType(RegistryValueKind ValueKind)
|
||||
{
|
||||
return ValueKind switch
|
||||
{
|
||||
RegistryValueKind.String or RegistryValueKind.ExpandString => typeof(string),
|
||||
RegistryValueKind.DWord => typeof(int),
|
||||
RegistryValueKind.QWord => typeof(long),
|
||||
RegistryValueKind.Binary => typeof(byte[]),
|
||||
RegistryValueKind.MultiString => typeof(string[]),
|
||||
_ => typeof(object),
|
||||
};
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region throw if invalid methods
|
||||
|
||||
/// <summary>
|
||||
/// Validates the specified RegistryHive value.
|
||||
/// </summary>
|
||||
/// <param name="hive">The RegistryHive value to validate.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when an unknown or unsupported RegistryHive value is provided.</exception>
|
||||
private static void ThrowIfHiveInvalid(RegistryHive Hive)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(RegistryHive), Hive) || Hive == RegistryHive.CurrentConfig || Hive == 0)
|
||||
throw new ArgumentException("Invalid parameter: Unknown or unsupported RegistryHive value.", nameof(Hive));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception if the specified path is null or empty.
|
||||
/// </summary>
|
||||
/// <param name="path">The path to validate.</param>
|
||||
/// <returns>The validated parameter path.</returns>
|
||||
private static void ThrowIfPathInvalid(string Path)
|
||||
{
|
||||
if (string.IsNullOrWhiteSpace(Path))
|
||||
throw new ArgumentException("Invalid parameter: Path cannot be null, empty, or consist only of whitespace characters.", nameof(Path));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception if the specified name is null or empty.
|
||||
/// </summary>
|
||||
/// <param name="name">The name to validate.</param>
|
||||
private static void ThrowIfNameInvalid(string Name)
|
||||
{
|
||||
if (Name == null)
|
||||
throw new ArgumentNullException(nameof(Name), "Invalid parameter: Name cannot be null.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Throws an exception if the specified RegistryValueKind is unknown.
|
||||
/// </summary>
|
||||
/// <param name="valueKind">The RegistryValueKind to validate.</param>
|
||||
/// <exception cref="InvalidOperationException">Thrown when the RegistryValueKind is Unknown.</exception>
|
||||
private static void ThrowIfValueKindInvalid(RegistryValueKind ValueKind)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(RegistryValueKind), ValueKind) || ValueKind == RegistryValueKind.Unknown || ValueKind == RegistryValueKind.None)
|
||||
throw new ArgumentException("Invalid parameter: Unknown or unsupported RegistryValueKind value.", nameof(ValueKind));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
904
mRemoteNG/Tools/WindowsRegistry/WinRegistryEntry.cs
Normal file
904
mRemoteNG/Tools/WindowsRegistry/WinRegistryEntry.cs
Normal file
@@ -0,0 +1,904 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Win32;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Represents an entry in the Windows Registry.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This class encapsulates the functionality needed to interact with Windows Registry entries,
|
||||
/// including reading and writing values. It provides a comprehensive set of methods to handle
|
||||
/// different value types, ensuring flexibility and ease of use.
|
||||
///
|
||||
/// Key features include:
|
||||
/// - Reading values from a specified registry path and name.
|
||||
/// - Writing values to a specified registry path and name.
|
||||
/// - Support for multiple data types such as strings, integers, and binary data.
|
||||
/// - Ability to specify the registry hive (e.g., HKEY_LOCAL_MACHINE, HKEY_CURRENT_USER).
|
||||
///
|
||||
/// This class is designed to simplify the manipulation of registry entries by providing a
|
||||
/// straightforward interface for common registry operations.
|
||||
///
|
||||
/// Example usage:
|
||||
/// <code>
|
||||
/// var registryEntry = new RegistryEntry<string>(RegistryHive.LocalMachine, @"Software\MyApp", "Settings");
|
||||
/// var value = registryEntry.Read();
|
||||
/// if (value != **)
|
||||
/// registryEntry.Write("newVal");
|
||||
/// </code>
|
||||
///
|
||||
/// <code>
|
||||
/// var registryEntry = new RegistryEntry<int>(RegistryHive.LocalMachine, @"Software\MyApp", "Settings").Read();
|
||||
/// </code>
|
||||
///
|
||||
/// <code>
|
||||
/// var registryEntry = new RegistryEntry<long>(RegistryHive.LocalMachine, @"Software\MyApp", "Settings").SetValidation(min, max).Read();
|
||||
/// if (registryEntry.IsValid())
|
||||
/// Do Something
|
||||
/// </code>
|
||||
///
|
||||
/// </remarks>
|
||||
public class WinRegistryEntry<T>
|
||||
{
|
||||
#region Registry Fileds & Properties
|
||||
|
||||
/// <summary>
|
||||
/// Represents the registry hive associated with the registry key.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default value is <see cref="RegistryHive.CurrentUser"/>.
|
||||
/// </remarks>
|
||||
public RegistryHive Hive
|
||||
{
|
||||
get { return privateHive; }
|
||||
set
|
||||
{
|
||||
privateHive =
|
||||
!Enum.IsDefined(typeof(RegistryHive), value) || value == RegistryHive.CurrentConfig || value == RegistryHive.ClassesRoot
|
||||
? throw new ArgumentException("Invalid parameter: Unknown or unsupported RegistryHive value.", nameof(Hive))
|
||||
: value;
|
||||
}
|
||||
}
|
||||
private RegistryHive privateHive = RegistryHive.CurrentUser;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the path of the registry entry.
|
||||
/// </summary>
|
||||
public string Path
|
||||
{
|
||||
get { return privatePath; }
|
||||
set
|
||||
{
|
||||
privatePath =
|
||||
!string.IsNullOrWhiteSpace(value)
|
||||
? value
|
||||
: throw new ArgumentNullException(nameof(Path), "Invalid parameter: Path cannot be null, empty, or consist only of whitespace characters.");
|
||||
}
|
||||
}
|
||||
private string privatePath;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the name of the registry entry.
|
||||
/// </summary>
|
||||
public string Name { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Represents the kind of data stored in the registry value.
|
||||
/// </summary>
|
||||
public RegistryValueKind ValueKind { get; private set; } = InitialRegistryValueKind();
|
||||
|
||||
/// <summary>
|
||||
/// Represents the value of the registry entry.
|
||||
/// </summary>
|
||||
public T Value
|
||||
{
|
||||
get { return privateValue; }
|
||||
set
|
||||
{
|
||||
privateValue = ValueValidationRules(value);
|
||||
}
|
||||
}
|
||||
private T privateValue;
|
||||
|
||||
#endregion
|
||||
|
||||
#region Aditional Fileds & Properties
|
||||
|
||||
private T[] AllowedValues;
|
||||
private int? MinInt32Value;
|
||||
private int? MaxInt32Value;
|
||||
private long? MinInt64Value;
|
||||
private long? MaxInt64Value;
|
||||
private Type EnumType;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the raw value retrieved directly from the registry.
|
||||
/// </summary>
|
||||
private string RawValue;
|
||||
|
||||
/// <summary>
|
||||
/// Represents the type of the generic parameter T.
|
||||
/// </summary>
|
||||
private readonly Type ElementType = typeof(T);
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the reading operation for the registry value was successful.
|
||||
/// </summary>
|
||||
private bool ReadOperationSucceeded;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether a lock operation should be performed after a successful read operation.
|
||||
/// </summary>
|
||||
private bool DoLock;
|
||||
|
||||
/// <summary>
|
||||
/// Indicates whether the WinRegistryEntry is currently locked, preventing further read operations.
|
||||
/// </summary>
|
||||
public bool IsLocked { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the entry has been explicitly set in the registry.
|
||||
/// This check is faster as it only verifies if a value was readed (set in registry).
|
||||
/// </summary>
|
||||
public bool IsSet => IsEntrySet();
|
||||
|
||||
/// <summary>
|
||||
/// Gets a value indicating whether the entry's value is valid according to custom validation rules.
|
||||
/// This check includes whether the value has been set and whether it adheres to the defined validation criteria.
|
||||
/// </summary>
|
||||
public bool IsValid => CheckIsValid();
|
||||
|
||||
#endregion
|
||||
|
||||
#region Constructors
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WinRegistryEntry{T}"/> class with default values.
|
||||
/// </summary>
|
||||
public WinRegistryEntry() { }
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WinRegistryEntry{T}"/> class for reading a default value from the specified registry hive and path.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
public WinRegistryEntry(RegistryHive hive, string path)
|
||||
{
|
||||
Hive = hive;
|
||||
Path = path;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WinRegistryEntry{T}"/> class for writing a default value to the specified registry hive and path.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
/// <param name="value">The value of the registry entry.</param>
|
||||
public WinRegistryEntry(RegistryHive hive, string path, T value)
|
||||
{
|
||||
Hive = hive;
|
||||
Path = path;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WinRegistryEntry{T}"/> class for reading a specific value from the specified registry hive, path, and name.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
/// <param name="name">The name of the registry entry.</param>
|
||||
public WinRegistryEntry(RegistryHive hive, string path, string name)
|
||||
{
|
||||
Hive = hive;
|
||||
Path = path;
|
||||
Name = name;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WinRegistryEntry{T}"/> class for writing a specific value to the specified registry hive, path, and name.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
/// <param name="name">The name of the registry entry.</param>
|
||||
/// <param name="value">The value of the registry entry.</param>
|
||||
public WinRegistryEntry(RegistryHive hive, string path, string name, T value)
|
||||
{
|
||||
Hive = hive;
|
||||
Path = path;
|
||||
Name = name;
|
||||
Value = value;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Factory Methods
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="WinRegistryEntry{T}"/> class for reading a default value from the specified registry hive and path.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
/// <returns>A new instance of the <see cref="WinRegistryEntry{T}"/> class.</returns>
|
||||
public static WinRegistryEntry<T> New(RegistryHive hive, string path)
|
||||
{
|
||||
return new WinRegistryEntry<T>(hive, path);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="WinRegistryEntry{T}"/> class for writing a value to the specified registry hive and path.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
/// <param name="value">The value of the registry entry.</param>
|
||||
/// <returns>A new instance of the <see cref="WinRegistryEntry{T}"/> class.</returns>
|
||||
public static WinRegistryEntry<T> New(RegistryHive hive, string path, T value)
|
||||
{
|
||||
return new WinRegistryEntry<T>(hive, path, value);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="WinRegistryEntry{T}"/> class for reading a specific value from the specified registry hive, path, and name.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
/// <param name="name">The name of the registry entry.</param>
|
||||
/// <returns>A new instance of the <see cref="WinRegistryEntry{T}"/> class.</returns>
|
||||
public static WinRegistryEntry<T> New(RegistryHive hive, string path, string name)
|
||||
{
|
||||
return new WinRegistryEntry<T>(hive, path, name);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new instance of the <see cref="WinRegistryEntry{T}"/> class for writing a specific value to the specified registry hive, path, and name.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive of the entry.</param>
|
||||
/// <param name="path">The path of the registry entry.</param>
|
||||
/// <param name="name">The name of the registry entry.</param>
|
||||
/// <param name="value">The value of the registry entry.</param>
|
||||
/// <returns>A new instance of the <see cref="WinRegistryEntry{T}"/> class.</returns>
|
||||
public static WinRegistryEntry<T> New(RegistryHive hive, string path, string name, T value)
|
||||
{
|
||||
return new WinRegistryEntry<T>(hive, path, name, value);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Public Methods
|
||||
|
||||
/// <summary>
|
||||
/// Sets the kind of the registry value, ensuring it is a valid and defined <see cref="RegistryValueKind"/>.
|
||||
/// </summary>
|
||||
/// <param name="valueKind">The registry value kind to set.</param>
|
||||
/// <returns>The current instance of <see cref="WinRegistryEntry{T}"/> to allow for method chaining.</returns>
|
||||
public WinRegistryEntry<T> SetValueKind(RegistryValueKind valueKind)
|
||||
{
|
||||
if (ValueKindValidationRule(valueKind))
|
||||
ValueKind = valueKind;
|
||||
else
|
||||
// Validation rule returned false, so the initial value will be used for the specified system type.
|
||||
// Nothing will be changed
|
||||
LogError("ValueKind is not valid and cannot be set.");
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the allowed values for validation, with an option for case sensitivity.
|
||||
/// </summary>
|
||||
/// <param name="allowedValues">The array of allowed values.</param>
|
||||
public WinRegistryEntry<T> SetValidation(T[] allowedValues)
|
||||
{
|
||||
ResetValidation();
|
||||
|
||||
if (allowedValues != null && allowedValues.Length > 0)
|
||||
{
|
||||
AllowedValues = allowedValues;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up validation using an array of allowed integer values.
|
||||
/// </summary>
|
||||
/// <param name="allowedValues">The array of allowed integer values.</param>
|
||||
public WinRegistryEntry<T> SetValidation(int[] allowedValues)
|
||||
{
|
||||
T[] mappedValues = allowedValues?.Select(value => (T)(object)value).ToArray();
|
||||
return SetValidation(mappedValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up validation using an array of allowed integer values.
|
||||
/// </summary>
|
||||
/// <param name="allowedValues">The array of allowed integer values.</param>
|
||||
public WinRegistryEntry<T> SetValidation(long[] allowedValues)
|
||||
{
|
||||
T[] mappedValues = allowedValues?.Select(value => (T)(object)value).ToArray();
|
||||
return SetValidation(mappedValues);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up validation for a range of integer values.
|
||||
/// </summary>
|
||||
/// <param name="minValue">The minimum value of the range.</param>
|
||||
/// <param name="maxValue">The maximum value of the range.</param>
|
||||
public WinRegistryEntry<T> SetValidation(int minValue, int maxValue)
|
||||
{
|
||||
ValidateRange(minValue, maxValue);
|
||||
ResetValidation();
|
||||
|
||||
MinInt32Value = minValue;
|
||||
MaxInt32Value = maxValue;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up validation for a range of integer values.
|
||||
/// </summary>
|
||||
/// <param name="minValue">The minimum value of the range.</param>
|
||||
/// <param name="maxValue">The maximum value of the range.</param>
|
||||
public WinRegistryEntry<T> SetValidation(long minValue, long maxValue)
|
||||
{
|
||||
ValidateRange(minValue, maxValue);
|
||||
ResetValidation();
|
||||
|
||||
MinInt64Value = minValue;
|
||||
MaxInt64Value = maxValue;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets up validation rules for a range of Int32, Int64 values.
|
||||
/// </summary>
|
||||
/// <param name="minValue">The minimum value of the range. "*" can be provided to indicate no minimum value.</param>
|
||||
/// <param name="maxValue">The maximum value of the range. "*" can be provided to indicate no maximum value.</param>
|
||||
/// <returns>The current instance of the WinRegistryEntry<T> class.</returns>
|
||||
/// <exception cref="ArgumentException">Thrown when the registry entry type is not a valid Int32 or Int64.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when an invalid minimum value is provided for Int32 or Int64.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when an invalid maximum value is provided for Int32 or Int64.</exception>
|
||||
|
||||
public WinRegistryEntry<T> SetValidation(string minValue, string maxValue)
|
||||
{
|
||||
if (string.IsNullOrEmpty(minValue) || minValue == "*")
|
||||
minValue = "0";
|
||||
if ((string.IsNullOrEmpty(maxValue) || maxValue == "*"))
|
||||
maxValue = (ElementType == typeof(int))
|
||||
? Int32.MaxValue.ToString()
|
||||
: Int64.MaxValue.ToString();
|
||||
|
||||
if (ElementType == typeof(int))
|
||||
{
|
||||
if (!int.TryParse(minValue, out int minIntValue))
|
||||
throw new ArgumentException("Invalid minimum value for Int32.");
|
||||
if (!int.TryParse(maxValue, out int maxIntValue))
|
||||
throw new ArgumentException("Invalid maximum value for Int32.");
|
||||
|
||||
return SetValidation(minIntValue, maxIntValue);
|
||||
}
|
||||
else if (ElementType == typeof(long))
|
||||
{
|
||||
if (!long.TryParse(minValue, out long minLongValue))
|
||||
throw new ArgumentException("Invalid minimum value for Int64.");
|
||||
if (!long.TryParse(maxValue, out long maxLongValue))
|
||||
throw new ArgumentException("Invalid maximum value for Int64.");
|
||||
|
||||
return SetValidation(minLongValue, maxLongValue);
|
||||
}
|
||||
else
|
||||
{
|
||||
throw new ArgumentException("Registry entry type must be either a valid Int32 or Int64 to use this validation.");
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Sets the validation to use an enumeration type
|
||||
/// </summary>
|
||||
/// <typeparam name="TEnum">The enumeration type.</typeparam>
|
||||
public WinRegistryEntry<T> SetValidation<TEnum>() where TEnum : Enum
|
||||
{
|
||||
ResetValidation();
|
||||
|
||||
Type enumType = typeof(TEnum);
|
||||
if (enumType != null)
|
||||
EnumType = enumType;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <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 IsReadable()
|
||||
{
|
||||
return IsHiveSet() && IsPathSet();
|
||||
}
|
||||
|
||||
/// <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
|
||||
/// </summary>
|
||||
/// <returns>Returns true if the key is write-ready, otherwise false.</returns>
|
||||
public bool IsWritable()
|
||||
{
|
||||
return IsHiveSet() && IsValueKindSet() && IsPathSet();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Reads the value of the registry entry from the specified registry path and assigns it to the Value property.
|
||||
/// </summary>
|
||||
/// <returns>The current instance of <see cref="WinRegistryEntry{T}"/> to allow for method chaining.</returns>
|
||||
public WinRegistryEntry<T> Read()
|
||||
{
|
||||
if (IsLocked)
|
||||
throw new InvalidOperationException("Operation denied: Cannot read registry entry again. Lock is enabled.");
|
||||
|
||||
if (!IsReadable())
|
||||
throw new InvalidOperationException("Unable to read registry key. Hive, path, and name are required.");
|
||||
|
||||
string rawValue = null;
|
||||
string name = string.IsNullOrEmpty(Name) ? null : Name;
|
||||
|
||||
try
|
||||
{
|
||||
using var key = RegistryKey.OpenBaseKey(Hive, RegistryView.Default).OpenSubKey(Path);
|
||||
if (key != null)
|
||||
RawValue = rawValue = key.GetValue(name)?.ToString();
|
||||
|
||||
if (rawValue != null)
|
||||
ValueKind = key.GetValueKind(name);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Error reading the Windows Registry.", ex);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(rawValue))
|
||||
{
|
||||
// Issue in Windows registry: Value was null or empty.
|
||||
string logName = string.IsNullOrEmpty(Name) ? "Default Value" : Name;
|
||||
LogInfo($"Value for {logName} is Null or Empty");
|
||||
}
|
||||
else if (!ValueKindValidationRule(ValueKind))
|
||||
{
|
||||
// Issue in Windows registry: Value kind of the value cannot be parsed to type T.
|
||||
LogError($"Cannot parse a Value of type {ValueKind} to the specified type {typeof(T).FullName}.");
|
||||
}
|
||||
else
|
||||
{
|
||||
Value = ConvertValueBasedOnType(rawValue);
|
||||
ReadOperationSucceeded = true;
|
||||
|
||||
if (DoLock)
|
||||
IsLocked = true;
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes the value of the registry entry to the specified registry path.
|
||||
/// </summary>
|
||||
/// <returns>The current instance of <see cref="WinRegistryEntry{T}"/> to allow for method chaining.</returns>
|
||||
public WinRegistryEntry<T> Write()
|
||||
{
|
||||
if (!IsWritable())
|
||||
throw new InvalidOperationException("Unable to write registry key. Hive, path, name, value kind, and value are required.");
|
||||
|
||||
string name = string.IsNullOrEmpty(Name) ? null : Name;
|
||||
RegistryValueKind valueKind = string.IsNullOrEmpty(Name) ? RegistryValueKind.String : ValueKind;
|
||||
|
||||
string value;
|
||||
if (typeof(T) == typeof(bool))
|
||||
{
|
||||
value = (bool)(object)Value
|
||||
? ValueKind == RegistryValueKind.DWord ? "1" : "True"
|
||||
: ValueKind == RegistryValueKind.DWord ? "0" : "False";
|
||||
}
|
||||
else
|
||||
{
|
||||
value = Value.ToString();
|
||||
}
|
||||
|
||||
try
|
||||
{
|
||||
using RegistryKey baseKey = RegistryKey.OpenBaseKey(Hive, RegistryView.Default);
|
||||
using RegistryKey registryKey = baseKey.CreateSubKey(Path, true);
|
||||
|
||||
registryKey.SetValue(name, value, valueKind);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Error writing to the Windows Registry.", ex);
|
||||
}
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Writes a new value to the registry entry.
|
||||
/// </summary>
|
||||
/// <param name="newValue">The new value to be written to the registry entry.</param>
|
||||
/// <returns>The current instance of <see cref="WinRegistryEntry{T}"/> to allow for method chaining.</returns>
|
||||
public WinRegistryEntry<T> Write(T newValue)
|
||||
{
|
||||
Value = newValue;
|
||||
return Write();
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Clears the current values of the instance.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// This method resets the values to their default states.
|
||||
/// After invoking this method, the "Validations" properties <c>IsSet</c> and <c>IsValid</c> will return <c>false</c>.
|
||||
/// This is useful in scenarios where the value needs to be validated through alternative mechanisms.
|
||||
/// </remarks>
|
||||
public void Clear()
|
||||
{
|
||||
RawValue = null;
|
||||
Value = default;
|
||||
ReadOperationSucceeded = false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Locks the WinRegistryEntry to prevent further read operations.
|
||||
/// If a read operation has already succeeded, the entry is immediately locked.
|
||||
/// If no read operation has been performed yet, a flag indicating the intention to lock after a successful read operation is set.
|
||||
/// </summary>
|
||||
/// <returns>The current instance of <see cref="WinRegistryEntry{T}"/> to allow for method chaining.</returns>
|
||||
public WinRegistryEntry<T> Lock()
|
||||
{
|
||||
if (ReadOperationSucceeded)
|
||||
IsLocked = true;
|
||||
else
|
||||
DoLock = true;
|
||||
|
||||
return this;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Converts a string value to the specified .NET data type <typeparamref name="T"/>.
|
||||
/// </summary>
|
||||
/// <typeparam name="T">The target .NET data type to which the value is converted.</typeparam>
|
||||
/// <param name="originalValue">The string value to be converted.</param>
|
||||
/// <returns>The converted value of type <typeparamref name="T"/>.</returns>
|
||||
/// <exception cref="InvalidOperationException">Thrown when Conversion for <typeparamref name="T"/> failed..</exception>
|
||||
/// <exception cref="InvalidOperationException">Thrown when Conversion not supported for type <typeparamref name="T"/>.</exception>
|
||||
private T ConvertValueBasedOnType(string originalValue)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (ElementType == typeof(string))
|
||||
{
|
||||
return (T)(object)originalValue;
|
||||
}
|
||||
else if (ElementType == typeof(int))
|
||||
{
|
||||
if (int.TryParse(originalValue, out int intValue))
|
||||
return (T)(object)intValue;
|
||||
}
|
||||
else if (ElementType == typeof(long))
|
||||
{
|
||||
if (long.TryParse(originalValue, out long longValue))
|
||||
return (T)(object)longValue;
|
||||
}
|
||||
else if (ElementType == typeof(bool))
|
||||
{
|
||||
if (bool.TryParse(originalValue, out bool boolValue))
|
||||
return (T)(object)boolValue;
|
||||
else if (int.TryParse(originalValue, out int intBool))
|
||||
return (T)(object)(intBool == 1);
|
||||
}
|
||||
}
|
||||
catch
|
||||
{
|
||||
throw new InvalidOperationException($"Conversion for '{ElementType}' failed.");
|
||||
}
|
||||
throw new InvalidOperationException($"Conversion not supported for type '{ElementType}'.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an error message to the standard error stream.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message to log.</param>
|
||||
private static void LogError(string message)
|
||||
{
|
||||
Console.Error.WriteLine($"Error: {message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Logs an info message to the standard error stream.
|
||||
/// </summary>
|
||||
/// <param name="message">The error message to log.</param>
|
||||
private static void LogInfo(string message)
|
||||
{
|
||||
Console.WriteLine($"Info: {message}");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the provided value based on its type-specific rules.
|
||||
/// </summary>
|
||||
/// <param name="value">The value to be validated.</param>
|
||||
/// <exception cref="ArgumentException">Thrown when <typeparamref name="T"/> is bool and value is not True, False, 0 or 1.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when <typeparamref name="T"/> is int/long and value is negative.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when Value type <typeparamref name="T"/> is not supported.</exception>
|
||||
private T ValueValidationRules(T value)
|
||||
{
|
||||
// Boolean values are either string or DWORD. Mapping is needed to update ValueKind.
|
||||
var booleanRegistryValueKindMap = new Dictionary<string, RegistryValueKind>
|
||||
{
|
||||
{ "true", RegistryValueKind.String },
|
||||
{ "false", RegistryValueKind.String },
|
||||
{ "0", RegistryValueKind.DWord },
|
||||
{ "1", RegistryValueKind.DWord }
|
||||
};
|
||||
|
||||
// For string elements, directly enforce validity and correct the input.
|
||||
if (ElementType == typeof(string))
|
||||
{
|
||||
return EnforceStringInputValidity(value);
|
||||
}
|
||||
// For boolean elements, check if the value is valid and convert it to the appropriate value kind.
|
||||
else if (ElementType == typeof(bool))
|
||||
{
|
||||
if (!booleanRegistryValueKindMap.TryGetValue(value.ToString().ToLower(), out var valueKind))
|
||||
throw new ArgumentException("Invalid value. Supported values are ci strings 'True'/'False' or numbers '0'/'1'.", nameof(value));
|
||||
|
||||
ValueKind = valueKind;
|
||||
return value;
|
||||
}
|
||||
// For integer or long elements, ensure the value is not negative.
|
||||
else if (ElementType == typeof(int) || ElementType == typeof(long))
|
||||
{
|
||||
if (Convert.ToInt64(value) < 0)
|
||||
throw new ArgumentException("Value cannot be negative.", nameof(value));
|
||||
return value;
|
||||
}
|
||||
// For byte elements, ensure the value is not null or empty.
|
||||
else if (ElementType == typeof(byte))
|
||||
{
|
||||
if (value == null || ((byte[])(object)value).Length == 0)
|
||||
throw new ArgumentException("Value cannot be null or empty.", nameof(value));
|
||||
return value;
|
||||
}
|
||||
|
||||
// For unsupported element types, throw an ArgumentException.
|
||||
throw new ArgumentException($"Value type '{ElementType.FullName}' is not supported.", nameof(value));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates and corrects a string value based on a set of allowed values or enumeration values.
|
||||
/// </summary>
|
||||
/// <param name="value">The input value to be validated and potentially corrected.</param>
|
||||
/// <returns>The validated and potentially corrected value.</returns>
|
||||
private T EnforceStringInputValidity(T value)
|
||||
{
|
||||
if (AllowedValues != null)
|
||||
{
|
||||
T matchedValue = AllowedValues.FirstOrDefault(v => v.ToString().Equals(value.ToString(), StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (matchedValue != null)
|
||||
// Correct the Value to ensure the correct spelling and avoid user typing mistakes
|
||||
return matchedValue;
|
||||
}
|
||||
else if (EnumType != null && EnumType.IsEnum)
|
||||
{
|
||||
var matchedEnumValue = Enum.GetValues(EnumType)
|
||||
.Cast<Enum>()
|
||||
.FirstOrDefault(e => e.ToString().Equals(value.ToString(), StringComparison.OrdinalIgnoreCase));
|
||||
|
||||
if (matchedEnumValue != null)
|
||||
// Correct the Value to ensure the correct spelling and avoid user typing mistakes
|
||||
return ConvertValueBasedOnType(matchedEnumValue.ToString());
|
||||
}
|
||||
|
||||
return value;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Private method to validate the range values.
|
||||
/// </summary>
|
||||
/// <typeparam name="U">The type of the values being validated.</typeparam>
|
||||
/// <param name="minValue">The minimum value of the range.</param>
|
||||
/// <param name="maxValue">The maximum value of the range.</param>
|
||||
/// <param name="type">The type of registry entry (used for error messages).</param>
|
||||
private static void ValidateRange<U>(U minValue, U maxValue) where U : IComparable<U>
|
||||
{
|
||||
Type typeCode = typeof(U);
|
||||
|
||||
string type =
|
||||
typeCode == typeof(int) ? "dword" :
|
||||
typeCode == typeof(long) ? "qword"
|
||||
: throw new ArgumentException("Registry entry type must be either Int32 or Int64 to use this validation.");
|
||||
|
||||
if (minValue.CompareTo(default(U)) < 0)
|
||||
throw new ArgumentException($"Negative value not allowed for {type} parameter.", nameof(minValue));
|
||||
if (maxValue.CompareTo(default(U)) < 0)
|
||||
throw new ArgumentException($"Negative value not allowed for {type} parameter.", nameof(maxValue));
|
||||
if (minValue.CompareTo(maxValue) > 0)
|
||||
throw new ArgumentException("MinValue must be less than or equal to MaxValue.");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates the specified registry value kind.
|
||||
/// </summary>
|
||||
/// <param name="valueKind">The registry value kind to validate.</param>
|
||||
/// <returns>The validated <see cref="RegistryValueKind"/>.</returns>
|
||||
/// <exception cref="ArgumentException">Thrown when Invalid parameter: Unknown or unsupported <typeparamref name="valueKind" value.</exception>
|
||||
/// <exception cref="ArgumentException">Thrown when Value type <typeparamref name="T"/> is not supported.</exception>
|
||||
private bool ValueKindValidationRule(RegistryValueKind valueKind)
|
||||
{
|
||||
if (!Enum.IsDefined(typeof(RegistryValueKind), valueKind) || valueKind == RegistryValueKind.Unknown || valueKind == RegistryValueKind.None || valueKind == 0)
|
||||
throw new ArgumentException("Invalid parameter: Unknown or unsupported RegistryValueKind value.", nameof(valueKind));
|
||||
|
||||
return Type.GetTypeCode(ElementType) switch
|
||||
{
|
||||
TypeCode.Boolean => valueKind == RegistryValueKind.String || valueKind == RegistryValueKind.DWord,
|
||||
TypeCode.Int32 => valueKind == RegistryValueKind.DWord,
|
||||
TypeCode.Int64 => valueKind == RegistryValueKind.QWord,
|
||||
TypeCode.Byte => valueKind == RegistryValueKind.Binary,
|
||||
TypeCode.String => valueKind == RegistryValueKind.String || valueKind == RegistryValueKind.DWord || valueKind == RegistryValueKind.QWord, // Strings are compatible with most data types.
|
||||
_ => throw new ArgumentException($"Value type '{ElementType.FullName}' is not supported.")
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines the initial RegistryValueKind based on the type <typeparamref name="T"/>.
|
||||
/// </summary>
|
||||
/// <returns>The initial RegistryValueKind determined by the type <typeparamref name="T"/>.</returns>
|
||||
private static RegistryValueKind InitialRegistryValueKind()
|
||||
{
|
||||
return Type.GetTypeCode(typeof(T)) switch
|
||||
{
|
||||
TypeCode.Int32 => RegistryValueKind.DWord,
|
||||
TypeCode.Int64 => RegistryValueKind.QWord,
|
||||
TypeCode.Boolean => RegistryValueKind.String,
|
||||
TypeCode.Byte => RegistryValueKind.Binary,
|
||||
_ => RegistryValueKind.String, // Default to String for unsupported types
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the registry entry has been set.
|
||||
/// </summary>
|
||||
private bool IsEntrySet() => RawValue != null && ReadOperationSucceeded;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the registry hive has been explicitly set.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the hive is set; otherwise, <c>false</c>.</returns>
|
||||
private bool IsHiveSet() => Hive != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the value kind of the registry entry has been explicitly set.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the value kind is set; otherwise, <c>false</c>.</returns>
|
||||
private bool IsValueKindSet() => ValueKind != 0;
|
||||
|
||||
/// <summary>
|
||||
/// Determines whether the path of the registry entry has been explicitly set.
|
||||
/// </summary>
|
||||
/// <returns><c>true</c> if the path is set; otherwise, <c>false</c>.</returns>
|
||||
private bool IsPathSet() => Path != null;
|
||||
|
||||
/// <summary>
|
||||
/// Checks if the current value is valid according to its type-specific rules and constraints.
|
||||
/// </summary>
|
||||
/// <returns>True if the value is valid; otherwise, false.</returns>
|
||||
private bool CheckIsValid()
|
||||
{
|
||||
if (!IsEntrySet()) return false;
|
||||
|
||||
return Type.GetTypeCode(ElementType) switch
|
||||
{
|
||||
TypeCode.String => ValidateString(),
|
||||
TypeCode.Boolean => true,
|
||||
TypeCode.Int32 => ValidateInt32(),
|
||||
TypeCode.Int64 => ValidateInt64(),
|
||||
_ => throw new ArgumentException($"Value type '{ElementType.FullName}' is not supported."),
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Resets all validation setup for the entry to their default values.
|
||||
/// This includes clearing allowed values, resetting case sensitivity, setting numeric ranges and enum types to null.
|
||||
/// </summary>
|
||||
private void ResetValidation()
|
||||
{
|
||||
AllowedValues = null;
|
||||
|
||||
MinInt32Value = null;
|
||||
MaxInt32Value = null;
|
||||
MinInt64Value = null;
|
||||
MaxInt64Value = null;
|
||||
|
||||
EnumType = null;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates a string value based on allowed values or enumeration values.
|
||||
/// </summary>
|
||||
/// <returns>True if the string value is valid; otherwise, false.</returns>
|
||||
private bool ValidateString()
|
||||
{
|
||||
if (AllowedValues != null)
|
||||
{
|
||||
//return AllowedValues.FirstOrDefault(v => v.ToString().Equals(Value.ToString(), StringComparison.OrdinalIgnoreCase)) != null;
|
||||
return AllowedValues.Contains(Value);
|
||||
}
|
||||
else if (EnumType != null && EnumType.IsEnum)
|
||||
{
|
||||
return Enum.GetValues(EnumType)
|
||||
.Cast<Enum>()
|
||||
.Any(e => e.ToString().Equals(Value.ToString(), StringComparison.OrdinalIgnoreCase));
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates an integer value based on allowed values, minimum and maximum values, or enumeration values.
|
||||
/// </summary>
|
||||
/// <returns>True if the integer value is valid; otherwise, false.</returns>
|
||||
private bool ValidateInt32()
|
||||
{
|
||||
int value = (int)(object)Value;
|
||||
|
||||
if (AllowedValues != null)
|
||||
return AllowedValues.Contains(Value);
|
||||
|
||||
else if (MinInt32Value != null && MaxInt32Value != null)
|
||||
return value >= MinInt32Value && value <= MaxInt32Value;
|
||||
|
||||
else if (EnumType != null && EnumType.IsEnum)
|
||||
{
|
||||
foreach (object enumValue in Enum.GetValues(EnumType))
|
||||
{
|
||||
if (Convert.ToInt32(enumValue) == value)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates a long integer value based on allowed values, minimum and maximum values, or enumeration values.
|
||||
/// </summary>
|
||||
/// <returns>True if the long integer value is valid; otherwise, false.</returns>
|
||||
private bool ValidateInt64()
|
||||
{
|
||||
long value = (long)(object)Value;
|
||||
|
||||
if (AllowedValues != null)
|
||||
return AllowedValues.Contains(Value);
|
||||
|
||||
else if (MinInt64Value != null && MaxInt64Value != null)
|
||||
return value >= MinInt64Value && value <= MaxInt64Value;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,531 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Security;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// This class interacting with the Windows Registry.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class WindowsRegistry : IRegistry, IRegistryRead, IRegistryWrite
|
||||
{
|
||||
#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)
|
||||
{
|
||||
if (hive == 0)
|
||||
throw new ArgumentException("Unknown or unsupported RegistryHive value.", nameof(hive));
|
||||
path.ThrowIfNull(nameof(path));
|
||||
|
||||
using (DisposableOptional<RegistryKey> 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 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);
|
||||
}
|
||||
|
||||
/// <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 string GetPropertyValue(RegistryHive hive, string path, string name)
|
||||
{
|
||||
if (hive == 0)
|
||||
throw new ArgumentException("Unknown or unsupported RegistryHive value.", nameof(hive));
|
||||
path.ThrowIfNull(nameof(path));
|
||||
name.ThrowIfNull(nameof(name));
|
||||
|
||||
using (DisposableOptional<RegistryKey> key = OpenSubKey(hive, path))
|
||||
{
|
||||
if (!key.Any())
|
||||
return null;
|
||||
|
||||
object keyValue = key.First().GetValue(name);
|
||||
|
||||
if (keyValue == null)
|
||||
return null;
|
||||
|
||||
return keyValue.ToString();
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean value from the Windows Registry based on the specified registry path and property name.
|
||||
/// If the value is not found or cannot be parsed, it returns a specified default value.
|
||||
/// </summary>
|
||||
/// <param name="hive">The Registry hive where the value is located.</param>
|
||||
/// <param name="path">The registry path to the key containing the property.</param>
|
||||
/// <param name="propertyName">The name of the property to retrieve.</param>
|
||||
/// <param name="defaultValue">The default value to return if the property is not found or cannot be parsed. Default is false.</param>
|
||||
/// <returns>The boolean value of the specified property or the default value if not found or cannot be parsed.</returns>
|
||||
public bool GetBoolValue(RegistryHive hive, string path, string propertyName, bool defaultValue = false)
|
||||
{
|
||||
string value = GetPropertyValue(hive, path, propertyName);
|
||||
|
||||
if (!string.IsNullOrEmpty(value))
|
||||
{
|
||||
if (int.TryParse(value, out int intValue))
|
||||
return intValue == 1;
|
||||
if (bool.TryParse(value, out bool boolValue))
|
||||
return boolValue;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
// <summary>
|
||||
/// Retrieves a DWORD value from the Windows Registry, with an optional default value.
|
||||
/// </summary>
|
||||
/// <param name="hive">The Registry hive to access.</param>
|
||||
/// <param name="path">The Registry path containing the key.</param>
|
||||
/// <param name="propertyName">The name of the Registry property.</param>
|
||||
/// <param name="defaultValue">The default value to return if the property is not found or cannot be parsed.</param>
|
||||
/// <returns>The DWORD value from the Registry, or the specified default value.</returns>
|
||||
public int GetDwordValue(RegistryHive hive, string path, string propertyName, int defaultValue = 0)
|
||||
{
|
||||
string value = GetPropertyValue(hive, path, propertyName);
|
||||
|
||||
if (int.TryParse(value, out int intValue))
|
||||
{
|
||||
return intValue;
|
||||
}
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
/// <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()
|
||||
{
|
||||
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)
|
||||
{
|
||||
object value = subKey.GetValue(key.Name);
|
||||
if (value != null)
|
||||
key.Value = value.ToString();
|
||||
|
||||
if (TestValueKindExists(subKey, key.Name, out RegistryValueKind 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 = [];
|
||||
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);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Deletes a registry key and its subkeys.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive to open.</param>
|
||||
/// <param name="path">The path of the registry key to delete.</param>
|
||||
/// <param name="ignoreNotFound">Set to true to ignore if the key is not found.</param>
|
||||
public void DeleteRegistryKey(RegistryHive hive, string path, bool ignoreNotFound = false)
|
||||
{
|
||||
try
|
||||
{
|
||||
using (RegistryKey key = RegistryKey.OpenBaseKey(hive, RegistryView.Default))
|
||||
{
|
||||
if (key != null)
|
||||
{
|
||||
key.DeleteSubKeyTree(path, ignoreNotFound);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
// Handle any exceptions according to your requirements
|
||||
Console.WriteLine($"Error deleting registry key: {ex.Message}");
|
||||
throw;
|
||||
}
|
||||
}
|
||||
#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));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <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>
|
||||
public 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>
|
||||
public 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);
|
||||
}
|
||||
}
|
||||
#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)
|
||||
{
|
||||
case RegistryHive.ClassesRoot:
|
||||
return new DisposableOptional<RegistryKey>(Registry.ClassesRoot.OpenSubKey(keyPath));
|
||||
case RegistryHive.CurrentConfig:
|
||||
return new DisposableOptional<RegistryKey>(Registry.CurrentConfig.OpenSubKey(keyPath));
|
||||
case RegistryHive.CurrentUser:
|
||||
return new DisposableOptional<RegistryKey>(Registry.CurrentUser.OpenSubKey(keyPath));
|
||||
case RegistryHive.Users:
|
||||
return new DisposableOptional<RegistryKey>(Registry.Users.OpenSubKey(keyPath));
|
||||
case RegistryHive.LocalMachine:
|
||||
return new DisposableOptional<RegistryKey>(Registry.LocalMachine.OpenSubKey(keyPath));
|
||||
default:
|
||||
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 error by writing to the Windows Registry key.</exception>
|
||||
private void CreateOrSetRegistryValue(WindowsRegistryKey key)
|
||||
{
|
||||
try
|
||||
{
|
||||
if (!key.IsKeyWritable())
|
||||
throw new ArgumentNullException("The Windows Registry key is not ready for writing.");
|
||||
|
||||
using RegistryKey baseKey = RegistryKey.OpenBaseKey(key.Hive, RegistryView.Default);
|
||||
RegistryKey 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 (Exception ex)
|
||||
{
|
||||
throw new InvalidOperationException("Error writing to the Windows Registry key.", ex);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,118 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using mRemoteNG.App.Info;
|
||||
using mRemoteNG.Security.SymmetricEncryption;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
/// <summary>
|
||||
/// Extends the functionality of interacting with the Windows Registry, building upon the base WindowsRegistry class.
|
||||
/// </summary>
|
||||
public class WindowsRegistryAdvanced : WindowsRegistry , IRegistryAdvanced, IRegistryAdvancedRead
|
||||
{
|
||||
#region dword methods
|
||||
/// <summary>
|
||||
/// Retrieves a DWORD (32-bit integer) value from the Windows Registry based on the specified registry information.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive.</param>
|
||||
/// <param name="path">The path to the registry key.</param>
|
||||
/// <param name="propertyName">The name of the registry property.</param>
|
||||
/// <param name="defaultValue">Optional default value to be used if the registry key is not present (default is null).</param>
|
||||
/// <returns>A WindowsRegistryKeyInteger instance representing the retrieved DWORD value.</returns>
|
||||
public WindowsRegistryKeyInteger GetInteger(RegistryHive hive, string path, string propertyName, int? defaultValue = null)
|
||||
{
|
||||
// Retrieve the Windows Registry key
|
||||
WindowsRegistryKey key = GetWindowsRegistryKey(hive, path, propertyName);
|
||||
|
||||
// Create a WindowsRegistryKeyInteger instance and initialize it from the retrieved key
|
||||
WindowsRegistryKeyInteger IntKey = new();
|
||||
IntKey.ConvertFromWindowsRegistryKey(key);
|
||||
|
||||
return IntKey;
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region string methods
|
||||
/// <summary>
|
||||
/// Retrieves a string value from the Windows Registry based on the specified registry information.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive.</param>
|
||||
/// <param name="path">The path to the registry key.</param>
|
||||
/// <param name="propertyName">The name of the registry property.</param>
|
||||
/// <param name="defaultValue">Optional default value to be used if the registry key is not present (default is null).</param>
|
||||
/// <returns>A WindowsRegistryKeyString instance representing the retrieved string value.</returns>
|
||||
public WindowsRegistryKeyString GetString(RegistryHive hive, string path, string propertyName, string defaultValue = null)
|
||||
{
|
||||
// Retrieve the Windows Registry key
|
||||
WindowsRegistryKey key = GetWindowsRegistryKey(hive, path, propertyName);
|
||||
|
||||
// Create a WindowsRegistryKeyString instance and initialize it from the retrieved key
|
||||
WindowsRegistryKeyString StrKey = new();
|
||||
StrKey.ConvertFromWindowsRegistryKey(key, defaultValue);
|
||||
|
||||
return StrKey;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Retrieves a string value from the Windows Registry based on the specified registry information and validates it against a set of allowed values.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive.</param>
|
||||
/// <param name="path">The path to the registry key.</param>
|
||||
/// <param name="propertyName">The name of the registry property.</param>
|
||||
/// <param name="allowedValues">An array of valid values against which the retrieved string is validated.</param>
|
||||
/// <param name="caseSensitive">Optional parameter indicating whether the validation is case-sensitive (default is false).</param>
|
||||
/// <returns>A WindowsRegistryKeyString instance representing the retrieved and validated string value.</returns>
|
||||
public WindowsRegistryKeyString GetStringValidated(RegistryHive hive, string path, string propertyName, string[] allowedValues, bool caseSensitive = false, string defaultValue = null)
|
||||
{
|
||||
// Retrieve the Windows Registry key
|
||||
WindowsRegistryKey key = GetWindowsRegistryKey(hive, path, propertyName);
|
||||
|
||||
// Create a WindowsRegistryKeyString instance and initialize it from the retrieved key
|
||||
WindowsRegistryKeyString StrKey = new()
|
||||
{
|
||||
AllowedValues = allowedValues,
|
||||
IsCaseSensitiveValidation = caseSensitive
|
||||
};
|
||||
StrKey.ConvertFromWindowsRegistryKey(key, defaultValue);
|
||||
|
||||
return StrKey;
|
||||
}
|
||||
|
||||
/*public WindowsRegistryKeySecureString GetSecureString(RegistryHive hive, string path, string propertyName)
|
||||
{
|
||||
// Retrieve the Windows Registry key, the key should be encrypted
|
||||
var key = GetWindowsRegistryKey(hive, path, propertyName);
|
||||
|
||||
// Create a WindowsRegistryKeyBoolean instance and initialize it from the retrieved key
|
||||
WindowsRegistryKeySecureString secureKey = new (); // class not exsists
|
||||
secureKey.ConvertFromWindowsRegistryKey(key); // no default possible!
|
||||
return secureKey
|
||||
}*/
|
||||
|
||||
#endregion
|
||||
|
||||
#region bool methods
|
||||
/// <summary>
|
||||
/// Retrieves a boolean value from the Windows Registry based on the specified registry information.
|
||||
/// </summary>
|
||||
/// <param name="hive">The registry hive.</param>
|
||||
/// <param name="path">The path to the registry key.</param>
|
||||
/// <param name="propertyName">The name of the registry property.</param>
|
||||
/// <param name="defaultValue">An optional default value to use if the registry key is not present or if the value is not a valid boolean.</param>
|
||||
/// <returns>A WindowsRegistryKeyBoolean instance representing the retrieved boolean value.</returns>
|
||||
public WindowsRegistryKeyBoolean GetBoolean(RegistryHive hive, string path, string propertyName, bool? defaultValue = null)
|
||||
{
|
||||
// Retrieve the Windows Registry key
|
||||
WindowsRegistryKey key = GetWindowsRegistryKey(hive, path, propertyName);
|
||||
|
||||
// Create a WindowsRegistryKeyBoolean instance and initialize it from the retrieved key
|
||||
WindowsRegistryKeyBoolean boolKey = new ();
|
||||
boolKey.ConvertFromWindowsRegistryKey(key, defaultValue);
|
||||
|
||||
return boolKey;
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,116 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using Microsoft.Win32;
|
||||
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a Windows Registry key with a default string value, providing a flexible abstraction for registry operations.
|
||||
/// This class can be extended by inherited classes to customize behavior for specific data types.
|
||||
/// </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 value
|
||||
public virtual string Value
|
||||
{
|
||||
get => _value;
|
||||
set
|
||||
{
|
||||
_value = value;
|
||||
UpdateIsProvidedState();
|
||||
}
|
||||
}
|
||||
private string _value;
|
||||
#endregion
|
||||
|
||||
public RegistryValueKind ValueKind { get; set; } = RegistryValueKind.Unknown;
|
||||
|
||||
public bool IsKeyPresent { get; set; } = false;
|
||||
#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 protected methods
|
||||
protected void UpdateIsProvidedState()
|
||||
{
|
||||
// Key is present when RegistryKey value is not null
|
||||
IsKeyPresent = Value != null;
|
||||
}
|
||||
|
||||
protected bool IsHiveSet() => Hive != 0;
|
||||
|
||||
protected bool IsValueKindSet() => ValueKind != 0;
|
||||
|
||||
protected bool IsPathSet() => Path != null;
|
||||
|
||||
protected bool IsNameSet() => Name != null;
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,75 +0,0 @@
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a boolean Windows Registry key, extending the base class WindowsRegistryKey.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class WindowsRegistryKeyBoolean : WindowsRegistryKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the default boolean value for a Windows Registry key.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default value is initially set to `false`.
|
||||
/// </remarks>
|
||||
public bool DefaultValue { get; private set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the boolean value for a Windows Registry key.
|
||||
/// </summary>
|
||||
public new bool Value
|
||||
{
|
||||
get => BoolValue;
|
||||
private set
|
||||
{
|
||||
BoolValue = value;
|
||||
UpdateIsProvidedState();
|
||||
}
|
||||
}
|
||||
private bool BoolValue;
|
||||
|
||||
/// <summary>
|
||||
/// Converts and initializes a WindowsRegistryKeyBoolean from a base WindowsRegistryKey, with an optional default value.
|
||||
/// </summary>
|
||||
/// <param name="baseKey">The base WindowsRegistryKey to convert from.</param>
|
||||
/// <param name="defaultValue">Optional default value to set for the WindowsRegistryKeyBoolean.</param>
|
||||
public void ConvertFromWindowsRegistryKey(WindowsRegistryKey baseKey, bool? defaultValue = null)
|
||||
{
|
||||
SetDefaultValue(defaultValue);
|
||||
FromBaseKey(baseKey);
|
||||
}
|
||||
|
||||
private void FromBaseKey(WindowsRegistryKey baseKey)
|
||||
{
|
||||
if (baseKey == null)
|
||||
throw new ArgumentNullException(nameof(baseKey));
|
||||
|
||||
Hive = baseKey.Hive;
|
||||
Path = baseKey.Path;
|
||||
Name = baseKey.Name;
|
||||
ValueKind = baseKey.ValueKind;
|
||||
IsKeyPresent = baseKey.IsKeyPresent;
|
||||
|
||||
ConvertToBool(baseKey.Value);
|
||||
}
|
||||
|
||||
private void SetDefaultValue(bool? defaultValue)
|
||||
{
|
||||
if (defaultValue.HasValue)
|
||||
DefaultValue = (bool)defaultValue;
|
||||
}
|
||||
|
||||
private void ConvertToBool(string newValue)
|
||||
{
|
||||
if (IsKeyPresent && bool.TryParse(newValue, out bool boolValue))
|
||||
BoolValue = boolValue;
|
||||
else if (IsKeyPresent && int.TryParse(newValue, out int intValue))
|
||||
BoolValue = intValue == 1;
|
||||
else
|
||||
BoolValue = DefaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,78 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a integer Windows Registry key, extending the base class WindowsRegistryKey.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class WindowsRegistryKeyInteger : WindowsRegistryKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the default integer value for a Windows Registry key.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// The default value is initially set to `-1`.
|
||||
/// </remarks>
|
||||
public int DefaultValue { get; private set; } = -1;
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets the integer value for a Windows Registry key.
|
||||
/// </summary>
|
||||
public new int Value
|
||||
{
|
||||
get => IntegerValue;
|
||||
private set
|
||||
{
|
||||
IntegerValue = value;
|
||||
UpdateIsProvidedState();
|
||||
}
|
||||
}
|
||||
private int IntegerValue;
|
||||
|
||||
/// <summary>
|
||||
/// Converts and initializes a WindowsRegistryKeyInteger from a base WindowsRegistryKey, with an optional default value.
|
||||
/// </summary>
|
||||
/// <param name="baseKey">The base WindowsRegistryKey to convert from.</param>
|
||||
/// <param name="defaultValue">Optional default value to set for the WindowsRegistryKeyBoolean.</param>
|
||||
public void ConvertFromWindowsRegistryKey(WindowsRegistryKey baseKey, int? defaultValue = null)
|
||||
{
|
||||
SetDefaultValue(defaultValue);
|
||||
FromBaseKey(baseKey);
|
||||
}
|
||||
|
||||
private void FromBaseKey(WindowsRegistryKey baseKey)
|
||||
{
|
||||
if (baseKey == null)
|
||||
throw new ArgumentNullException(nameof(baseKey));
|
||||
|
||||
Hive = baseKey.Hive;
|
||||
Path = baseKey.Path;
|
||||
Name = baseKey.Name;
|
||||
ValueKind = baseKey.ValueKind;
|
||||
IsKeyPresent = baseKey.IsKeyPresent;
|
||||
|
||||
ConvertToInteger(baseKey.Value);
|
||||
}
|
||||
|
||||
private void SetDefaultValue (int? defaultValue)
|
||||
{
|
||||
if (defaultValue.HasValue)
|
||||
DefaultValue = (int)defaultValue;
|
||||
}
|
||||
|
||||
private void ConvertToInteger(string newValue)
|
||||
{
|
||||
if (ValueKind != RegistryValueKind.DWord)
|
||||
IsKeyPresent = false;
|
||||
|
||||
if (IsKeyPresent && int.TryParse(newValue.ToString(), out int intValue))
|
||||
IntegerValue = intValue;
|
||||
else
|
||||
IntegerValue = DefaultValue;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,121 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using System;
|
||||
using System.Linq;
|
||||
using System.Runtime.Versioning;
|
||||
|
||||
namespace mRemoteNG.Tools.WindowsRegistry
|
||||
{
|
||||
/// <summary>
|
||||
/// Represents a string Windows Registry key, extending the base class WindowsRegistryKey, can be evaluated with a value set.
|
||||
/// </summary>
|
||||
[SupportedOSPlatform("windows")]
|
||||
public class WindowsRegistryKeyString : WindowsRegistryKey
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets or sets the default integer value for a Windows Registry key.
|
||||
/// </summary>
|
||||
public string DefaultValue { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets an array of allowed values for validation.
|
||||
/// </summary>
|
||||
public string[] AllowedValues { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Gets or sets a boolean flag indicating whether validation is case-sensitive.
|
||||
/// </summary>
|
||||
public bool IsCaseSensitiveValidation { get; set; } = false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a boolean indicating whether the value is valid based on the validation rules.
|
||||
/// </summary>
|
||||
public bool IsValid { get; private set; } = false;
|
||||
|
||||
|
||||
public new string Value
|
||||
{
|
||||
get => StringValue;
|
||||
private set
|
||||
{
|
||||
StringValue = value;
|
||||
UpdateIsProvidedState();
|
||||
Validate();
|
||||
}
|
||||
}
|
||||
private string StringValue;
|
||||
|
||||
/// <summary>
|
||||
/// Converts and initializes a WindowsRegistryKeyString from a base WindowsRegistryKey, with an optional default value.
|
||||
/// </summary>
|
||||
/// <param name="baseKey">The base WindowsRegistryKey to convert from.</param>
|
||||
/// <param name="defaultValue">Optional default value to set for the WindowsRegistryKeyBoolean.</param>
|
||||
public void ConvertFromWindowsRegistryKey(WindowsRegistryKey baseKey, string defaultValue = null)
|
||||
{
|
||||
SetDefaultValue(defaultValue);
|
||||
FromBaseKey(baseKey);
|
||||
Validate();
|
||||
}
|
||||
|
||||
private void FromBaseKey(WindowsRegistryKey baseKey)
|
||||
{
|
||||
if (baseKey == null)
|
||||
throw new ArgumentNullException(nameof(baseKey));
|
||||
|
||||
Hive = baseKey.Hive;
|
||||
Path = baseKey.Path;
|
||||
Name = baseKey.Name;
|
||||
ValueKind = baseKey.ValueKind;
|
||||
IsKeyPresent = baseKey.IsKeyPresent;
|
||||
|
||||
ConvertToString(baseKey.Value);
|
||||
}
|
||||
|
||||
private void SetDefaultValue (string defaultValue)
|
||||
{
|
||||
DefaultValue = defaultValue;
|
||||
}
|
||||
private void ConvertToString(string newValue)
|
||||
{
|
||||
if (IsKeyPresent && newValue != null)
|
||||
StringValue = newValue;
|
||||
else
|
||||
StringValue = DefaultValue;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Validates a Windows Registry key value against a set of allowed values, considering case sensitivity.
|
||||
/// </summary>
|
||||
/// <param name="allowedValues">Array of allowed values.</param>
|
||||
/// <param name="caseSensitive">Optional parameter to specify case sensitivity in validation.</param>
|
||||
public void Validate(string[] allowedValues = null, bool? caseSensitive = null)
|
||||
{
|
||||
// Key must be present to evaluate
|
||||
if (!IsKeyPresent)
|
||||
return;
|
||||
|
||||
if (caseSensitive.HasValue)
|
||||
IsCaseSensitiveValidation = caseSensitive.Value;
|
||||
|
||||
if (allowedValues != null && allowedValues.Length >= 1)
|
||||
AllowedValues = allowedValues;
|
||||
|
||||
// AllowedValues array cannot be null or empty.
|
||||
if (AllowedValues == null || AllowedValues.Length == 0 || !IsKeyPresent)
|
||||
return;
|
||||
|
||||
if (IsKeyPresent && AllowedValues.Any(v =>
|
||||
IsCaseSensitiveValidation ? v == Value : v.Equals(Value, StringComparison.OrdinalIgnoreCase)))
|
||||
{
|
||||
// Set to true when the value is found in the valid values
|
||||
IsValid = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
// Set to false when the value is not found in the valid values
|
||||
IsValid = false;
|
||||
StringValue = DefaultValue;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@@ -43,7 +43,7 @@
|
||||
lblCredentialsDomain = new Controls.MrngLabel();
|
||||
radCredentialsNoInfo = new Controls.MrngRadioButton();
|
||||
radCredentialsCustom = new Controls.MrngRadioButton();
|
||||
lblCredentialsAdminInfo = new System.Windows.Forms.Label();
|
||||
lblRegistrySettingsUsedInfo = new System.Windows.Forms.Label();
|
||||
lblCredentialsGeneratorHelp = new Controls.MrngLabel();
|
||||
btnCredentialsGenerator = new System.Windows.Forms.Button();
|
||||
lblCredentialsGenerator = new Controls.MrngLabel();
|
||||
@@ -56,7 +56,7 @@
|
||||
// pnlDefaultCredentials
|
||||
//
|
||||
pnlDefaultCredentials.Controls.Add(pnlCredentialsSettingsPanel);
|
||||
pnlDefaultCredentials.Controls.Add(lblCredentialsAdminInfo);
|
||||
pnlDefaultCredentials.Controls.Add(lblRegistrySettingsUsedInfo);
|
||||
pnlDefaultCredentials.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
pnlDefaultCredentials.Location = new System.Drawing.Point(0, 0);
|
||||
pnlDefaultCredentials.Name = "pnlDefaultCredentials";
|
||||
@@ -149,6 +149,7 @@
|
||||
txtCredentialsPassword.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
txtCredentialsPassword.Location = new System.Drawing.Point(163, 55);
|
||||
txtCredentialsPassword.Name = "txtCredentialsPassword";
|
||||
txtCredentialsPassword.PasswordChar = '*';
|
||||
txtCredentialsPassword.Size = new System.Drawing.Size(166, 22);
|
||||
txtCredentialsPassword.TabIndex = 7;
|
||||
//
|
||||
@@ -232,18 +233,18 @@
|
||||
radCredentialsCustom.UseVisualStyleBackColor = false;
|
||||
radCredentialsCustom.CheckedChanged += radCredentialsCustom_CheckedChanged;
|
||||
//
|
||||
// lblCredentialsAdminInfo
|
||||
// lblRegistrySettingsUsedInfo
|
||||
//
|
||||
lblCredentialsAdminInfo.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||
lblCredentialsAdminInfo.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
lblCredentialsAdminInfo.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
lblCredentialsAdminInfo.Location = new System.Drawing.Point(0, 0);
|
||||
lblCredentialsAdminInfo.Name = "lblCredentialsAdminInfo";
|
||||
lblCredentialsAdminInfo.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
lblCredentialsAdminInfo.Size = new System.Drawing.Size(610, 30);
|
||||
lblCredentialsAdminInfo.TabIndex = 0;
|
||||
lblCredentialsAdminInfo.Text = "Some settings are configured by your Administrator. Please contact your administrator for more information.";
|
||||
lblCredentialsAdminInfo.Visible = false;
|
||||
lblRegistrySettingsUsedInfo.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||
lblRegistrySettingsUsedInfo.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
lblRegistrySettingsUsedInfo.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
lblRegistrySettingsUsedInfo.Location = new System.Drawing.Point(0, 0);
|
||||
lblRegistrySettingsUsedInfo.Name = "lblRegistrySettingsUsedInfo";
|
||||
lblRegistrySettingsUsedInfo.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
lblRegistrySettingsUsedInfo.Size = new System.Drawing.Size(610, 30);
|
||||
lblRegistrySettingsUsedInfo.TabIndex = 0;
|
||||
lblRegistrySettingsUsedInfo.Text = "Some settings are configured by your Administrator. Please contact your administrator for more information.";
|
||||
lblRegistrySettingsUsedInfo.Visible = false;
|
||||
//
|
||||
// lblCredentialsGeneratorHelp
|
||||
//
|
||||
@@ -304,7 +305,7 @@
|
||||
internal Controls.MrngTextBox txtCredentialsUsername;
|
||||
internal Controls.MrngLabel lblCredentialsDomain;
|
||||
private System.Windows.Forms.TableLayoutPanel tableLayoutPanel1;
|
||||
internal System.Windows.Forms.Label lblCredentialsAdminInfo;
|
||||
internal System.Windows.Forms.Label lblRegistrySettingsUsedInfo;
|
||||
internal System.Windows.Forms.Panel pnlCredentialsSettingsPanel;
|
||||
internal Controls.MrngLabel lblCredentialsGenerator;
|
||||
internal System.Windows.Forms.TextBox txtCredentialsGeneratorPsswd;
|
||||
|
||||
@@ -5,6 +5,7 @@ using mRemoteNG.Security.SymmetricEncryption;
|
||||
using mRemoteNG.Resources.Language;
|
||||
using System.Runtime.Versioning;
|
||||
using mRemoteNG.Config.Settings.Registry;
|
||||
using System.DirectoryServices;
|
||||
|
||||
namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
@@ -13,8 +14,6 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
#region Private Fields
|
||||
private readonly OptRegistryCredentialsPage _RegistrySettings = new();
|
||||
private bool _pageEnabled = true;
|
||||
|
||||
#endregion
|
||||
|
||||
public CredentialsPage()
|
||||
@@ -40,27 +39,28 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
lblCredentialsUsername.Text = Language.Username;
|
||||
lblCredentialsPassword.Text = Language.Password;
|
||||
lblCredentialsDomain.Text = Language.Domain;
|
||||
lblCredentialsAdminInfo.Text = Language.OptionsAdminInfo;
|
||||
lblRegistrySettingsUsedInfo.Text = Language.OptionsCompanyPolicyMessage;
|
||||
}
|
||||
|
||||
public override void LoadSettings()
|
||||
{
|
||||
if (!_pageEnabled) { return; }
|
||||
if (!_RegistrySettings.CredentialPageEnabled)
|
||||
return;
|
||||
|
||||
// ReSharper disable once SwitchStatementMissingSomeCases
|
||||
switch (Properties.OptionsCredentialsPage.Default.EmptyCredentials)
|
||||
{
|
||||
case "noinfo":
|
||||
radCredentialsNoInfo.Checked = true;
|
||||
break;
|
||||
case "windows":
|
||||
radCredentialsWindows.Checked = true;
|
||||
break;
|
||||
case "custom":
|
||||
radCredentialsCustom.Checked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case "noinfo":
|
||||
radCredentialsNoInfo.Checked = true;
|
||||
break;
|
||||
case "windows":
|
||||
radCredentialsWindows.Checked = true;
|
||||
break;
|
||||
case "custom":
|
||||
radCredentialsCustom.Checked = true;
|
||||
break;
|
||||
}
|
||||
|
||||
txtCredentialsUsername.Text = Properties.OptionsCredentialsPage.Default.DefaultUsername;
|
||||
LegacyRijndaelCryptographyProvider cryptographyProvider = new();
|
||||
txtCredentialsPassword.Text = cryptographyProvider.Decrypt(Properties.OptionsCredentialsPage.Default.DefaultPassword, Runtime.EncryptionKey);
|
||||
@@ -92,13 +92,19 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
public override void LoadRegistrySettings()
|
||||
{
|
||||
if (!CommonRegistrySettings.AllowModifyCredentialSettings)
|
||||
// CredentialPageEnabled reg setting: enabled/default: true; Disabled: false.
|
||||
if (!_RegistrySettings.CredentialPageEnabled)
|
||||
{
|
||||
DisablePage();
|
||||
return;
|
||||
}
|
||||
|
||||
if (_RegistrySettings.UseCredentials.IsKeyPresent)
|
||||
// UseCredentials reg setting with validation:
|
||||
// 1. Is not set or valid, stop processing.
|
||||
// 2. Set the 'EmptyCredentials' option based on value
|
||||
// 3. Only proceed when "custom"
|
||||
if (!_RegistrySettings.UseCredentials.IsValid) { return; }
|
||||
else if (_RegistrySettings.UseCredentials.IsValid)
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.EmptyCredentials = _RegistrySettings.UseCredentials.Value;
|
||||
|
||||
@@ -107,11 +113,13 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
case "noinfo":
|
||||
DisableControl(radCredentialsWindows);
|
||||
DisableControl(radCredentialsCustom);
|
||||
break;
|
||||
SetVisibilitySettingsUsedInfo();
|
||||
return;
|
||||
case "windows":
|
||||
DisableControl(radCredentialsNoInfo);
|
||||
DisableControl(radCredentialsCustom);
|
||||
break;
|
||||
SetVisibilitySettingsUsedInfo();
|
||||
return;
|
||||
case "custom":
|
||||
DisableControl(radCredentialsNoInfo);
|
||||
DisableControl(radCredentialsWindows);
|
||||
@@ -119,95 +127,87 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
}
|
||||
}
|
||||
|
||||
if (_RegistrySettings.UseCredentials.Value != "custom") { return; }
|
||||
// ***
|
||||
// The following is only used when set to custom!
|
||||
|
||||
|
||||
if (!CommonRegistrySettings.AllowSaveUsernames)
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.DefaultUsername = "";
|
||||
DisableControl(txtCredentialsUsername);
|
||||
}
|
||||
else if (_RegistrySettings.DefaultUsername.IsKeyPresent)
|
||||
// DefaultUsername reg setting: set DefaultUsername option based on value
|
||||
if (_RegistrySettings.DefaultUsername.IsSet)
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.DefaultUsername = _RegistrySettings.DefaultUsername.Value;
|
||||
DisableControl(txtCredentialsUsername);
|
||||
}
|
||||
|
||||
if (!CommonRegistrySettings.AllowSavePasswords)
|
||||
// DefaultPassword reg setting:
|
||||
// 1. Test decription works to prevents potential issues
|
||||
// 2. Set DefaultPassword option based on value
|
||||
// 3. Clears reg setting if fails
|
||||
if (_RegistrySettings.DefaultPassword.IsSet)
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.DefaultPassword = "";
|
||||
DisableControl(txtCredentialsPassword);
|
||||
}
|
||||
//else if (_RegistrySettings.DefaultPassword.IsKeyPresent)
|
||||
//{
|
||||
// Properties.OptionsCredentialsPage.Default.DefaultPassword = _RegistrySettings.DefaultPassword.Value;
|
||||
// DisableControl(txtCredentialsPassword);
|
||||
//}
|
||||
try
|
||||
{
|
||||
LegacyRijndaelCryptographyProvider cryptographyProvider = new();
|
||||
string decryptedPassword;
|
||||
string defaultPassword = _RegistrySettings.DefaultPassword.Value;
|
||||
|
||||
if (_RegistrySettings.DefaultDomain.IsKeyPresent)
|
||||
decryptedPassword = cryptographyProvider.Decrypt(defaultPassword, Runtime.EncryptionKey);
|
||||
Properties.OptionsCredentialsPage.Default.DefaultPassword = defaultPassword;
|
||||
DisableControl(txtCredentialsPassword);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Fire-and-forget: The DefaultPassword in the registry is not encrypted.
|
||||
_RegistrySettings.DefaultPassword.Clear();
|
||||
}
|
||||
}
|
||||
|
||||
// DefaultDomain reg setting: set DefaultDomain option based on value
|
||||
if (_RegistrySettings.DefaultDomain.IsSet)
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.DefaultDomain = _RegistrySettings.DefaultDomain.Value;
|
||||
DisableControl(txtCredentialsDomain);
|
||||
}
|
||||
|
||||
if (!CommonRegistrySettings.AllowSaveUsernames)
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.UserViaAPIDefault = "";
|
||||
DisableControl(txtCredentialsUserViaAPI);
|
||||
}
|
||||
else if (_RegistrySettings.UserViaAPIDefault.IsKeyPresent)
|
||||
// UserViaAPIDefault reg setting: set UserViaAPIDefault option based on value
|
||||
if (_RegistrySettings.UserViaAPIDefault.IsSet)
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.UserViaAPIDefault = _RegistrySettings.UserViaAPIDefault.Value;
|
||||
DisableControl(txtCredentialsUserViaAPI);
|
||||
}
|
||||
|
||||
lblCredentialsAdminInfo.Visible = ShowAdministratorInfo();
|
||||
SetVisibilitySettingsUsedInfo();
|
||||
}
|
||||
|
||||
public override bool ShowAdministratorInfo()
|
||||
/// <summary>
|
||||
/// Checks if any credantil registry settings are being used.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True if any relevant registry settings are used; otherwise, false.
|
||||
/// </returns>
|
||||
public override bool ShowRegistrySettingsUsedInfo()
|
||||
{
|
||||
return !CommonRegistrySettings.AllowModifyCredentialSettings
|
||||
|| !CommonRegistrySettings.AllowExportPasswords
|
||||
return !CommonRegistrySettings.AllowExportPasswords
|
||||
|| !CommonRegistrySettings.AllowExportUsernames
|
||||
|| !CommonRegistrySettings.AllowSavePasswords
|
||||
|| !CommonRegistrySettings.AllowSaveUsernames
|
||||
|| _RegistrySettings.DefaultUsername.IsKeyPresent
|
||||
//|| _RegistrySettings.DefaultPassword.IsKeyPresent
|
||||
|| _RegistrySettings.DefaultDomain.IsKeyPresent
|
||||
|| _RegistrySettings.UserViaAPIDefault.IsKeyPresent;
|
||||
}
|
||||
|
||||
private void radCredentialsCustom_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!_RegistrySettings.DefaultUsername.IsKeyPresent && CommonRegistrySettings.AllowSaveUsernames)
|
||||
{
|
||||
lblCredentialsUsername.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsUsername.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
|
||||
if (/*!_RegistrySettings.DefaultPassword.IsKeyPresent &&*/ CommonRegistrySettings.AllowSavePasswords)
|
||||
{
|
||||
lblCredentialsPassword.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsPassword.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
|
||||
if (!_RegistrySettings.DefaultDomain.IsKeyPresent)
|
||||
{
|
||||
lblCredentialsDomain.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsDomain.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
|
||||
if (!_RegistrySettings.UserViaAPIDefault.IsKeyPresent)
|
||||
{
|
||||
lblCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
|| !_RegistrySettings.CredentialPageEnabled
|
||||
|| _RegistrySettings.UseCredentials.IsValid;
|
||||
|
||||
/*
|
||||
* Checking these values is unnecessary because UseCredentials must be valid and set to Custom.
|
||||
*
|
||||
||_RegistrySettings.DefaultUsername.IsSet
|
||||
|| _RegistrySettings.DefaultPassword.IsSet
|
||||
|| _RegistrySettings.DefaultDomain.IsSet
|
||||
|| _RegistrySettings.UserViaAPIDefault.IsSet;
|
||||
*/
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables the page by setting default values and disabling controls.
|
||||
/// </summary>
|
||||
public override void DisablePage()
|
||||
{
|
||||
Properties.OptionsCredentialsPage.Default.EmptyCredentials = "noinfo";
|
||||
//radCredentialsNoInfo.Enabled = false;
|
||||
radCredentialsWindows.Enabled = false;
|
||||
radCredentialsCustom.Enabled = false;
|
||||
|
||||
@@ -216,8 +216,50 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
txtCredentialsDomain.Enabled = false;
|
||||
txtCredentialsUserViaAPI.Enabled = false;
|
||||
|
||||
lblCredentialsAdminInfo.Visible = true;
|
||||
_pageEnabled = false;
|
||||
SetVisibilitySettingsUsedInfo();
|
||||
}
|
||||
|
||||
#region Event Handlers
|
||||
|
||||
private void radCredentialsCustom_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!_RegistrySettings.DefaultUsername.IsSet && CommonRegistrySettings.AllowSaveUsernames)
|
||||
{
|
||||
lblCredentialsUsername.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsUsername.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
|
||||
if (!_RegistrySettings.DefaultPassword.IsSet && CommonRegistrySettings.AllowSavePasswords)
|
||||
{
|
||||
lblCredentialsPassword.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsPassword.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
|
||||
if (!_RegistrySettings.DefaultDomain.IsSet)
|
||||
{
|
||||
lblCredentialsDomain.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsDomain.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
|
||||
if (!_RegistrySettings.UserViaAPIDefault.IsSet && CommonRegistrySettings.AllowSaveUsernames)
|
||||
{
|
||||
lblCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
|
||||
txtCredentialsUserViaAPI.Enabled = radCredentialsCustom.Checked;
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Updates the visibility of the information label indicating whether registry settings are used.
|
||||
/// </summary>
|
||||
private void SetVisibilitySettingsUsedInfo()
|
||||
{
|
||||
lblRegistrySettingsUsedInfo.Visible = ShowRegistrySettingsUsedInfo();
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,4 +1,64 @@
|
||||
<root>
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<root>
|
||||
<!--
|
||||
Microsoft ResX Schema
|
||||
|
||||
Version 2.0
|
||||
|
||||
The primary goals of this format is to allow a simple XML format
|
||||
that is mostly human readable. The generation and parsing of the
|
||||
various data types are done through the TypeConverter classes
|
||||
associated with the data types.
|
||||
|
||||
Example:
|
||||
|
||||
... ado.net/XML headers & schema ...
|
||||
<resheader name="resmimetype">text/microsoft-resx</resheader>
|
||||
<resheader name="version">2.0</resheader>
|
||||
<resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
|
||||
<resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
|
||||
<data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
|
||||
<data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
|
||||
<data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
|
||||
<value>[base64 mime encoded serialized .NET Framework object]</value>
|
||||
</data>
|
||||
<data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
|
||||
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
|
||||
<comment>This is a comment</comment>
|
||||
</data>
|
||||
|
||||
There are any number of "resheader" rows that contain simple
|
||||
name/value pairs.
|
||||
|
||||
Each data row contains a name, and value. The row also contains a
|
||||
type or mimetype. Type corresponds to a .NET class that support
|
||||
text/value conversion through the TypeConverter architecture.
|
||||
Classes that don't support this are serialized and stored with the
|
||||
mimetype set.
|
||||
|
||||
The mimetype is used for serialized objects, and tells the
|
||||
ResXResourceReader how to depersist the object. This is currently not
|
||||
extensible. For a given mimetype the value must be set accordingly:
|
||||
|
||||
Note - application/x-microsoft.net.object.binary.base64 is the format
|
||||
that the ResXResourceWriter will generate, however the reader can
|
||||
read any of the formats listed below.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.binary.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.soap.base64
|
||||
value : The object must be serialized with
|
||||
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
|
||||
: and then encoded with base64 encoding.
|
||||
|
||||
mimetype: application/x-microsoft.net.object.bytearray.base64
|
||||
value : The object must be serialized into a byte array
|
||||
: using a System.ComponentModel.TypeConverter
|
||||
: and then encoded with base64 encoding.
|
||||
-->
|
||||
<xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
|
||||
<xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
|
||||
<xsd:element name="root" msdata:IsDataSet="true">
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using System.ComponentModel;
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Drawing;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Windows.Forms;
|
||||
@@ -42,13 +43,27 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
public virtual void RevertSettings()
|
||||
{
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Loads registry settings related to update options and proxy configurations.
|
||||
/// This method retrieves values from the registry and initializes the corresponding controls
|
||||
/// on the page with these values. It also updates internal flags and properties accordingly.
|
||||
/// </summary>
|
||||
public virtual void LoadRegistrySettings()
|
||||
{
|
||||
}
|
||||
public virtual bool ShowAdministratorInfo()
|
||||
|
||||
/// <summary>
|
||||
/// Determines if any registry settings are being used.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// A boolean value indicating whether registry settings are used, as determined by the configuration on the options page.
|
||||
/// </returns>
|
||||
public virtual bool ShowRegistrySettingsUsedInfo()
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
public virtual void DisablePage()
|
||||
{
|
||||
}
|
||||
@@ -94,10 +109,8 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
((TextBox)control).ReadOnly = control.Enabled;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
internal class DropdownList
|
||||
internal class DropdownList
|
||||
{
|
||||
public int Index { get; set; }
|
||||
public string DisplayString { get; set; }
|
||||
|
||||
@@ -56,7 +56,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
btnTestProxy = new MrngButton();
|
||||
groupBoxReleaseChannel = new MrngGroupBox();
|
||||
pnlDefaultUpdate = new System.Windows.Forms.Panel();
|
||||
lblUpdateAdminInfo = new System.Windows.Forms.Label();
|
||||
lblRegistrySettingsUsedInfo = new System.Windows.Forms.Label();
|
||||
pnlUpdateCheck.SuspendLayout();
|
||||
pnlProxy.SuspendLayout();
|
||||
tblProxyBasic.SuspendLayout();
|
||||
@@ -97,6 +97,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
cboUpdateCheckFrequency.Name = "cboUpdateCheckFrequency";
|
||||
cboUpdateCheckFrequency.Size = new System.Drawing.Size(120, 21);
|
||||
cboUpdateCheckFrequency.TabIndex = 1;
|
||||
cboUpdateCheckFrequency.Enabled = false;
|
||||
//
|
||||
// btnUpdateCheckNow
|
||||
//
|
||||
@@ -137,7 +138,6 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
//
|
||||
// cboReleaseChannel
|
||||
//
|
||||
cboReleaseChannel._mice = MrngComboBox.MouseState.HOVER;
|
||||
cboReleaseChannel.DropDownStyle = System.Windows.Forms.ComboBoxStyle.DropDownList;
|
||||
cboReleaseChannel.FormattingEnabled = true;
|
||||
cboReleaseChannel.Location = new System.Drawing.Point(7, 21);
|
||||
@@ -273,6 +273,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
txtProxyPassword.Font = new System.Drawing.Font("Segoe UI", 8.25F, System.Drawing.FontStyle.Regular, System.Drawing.GraphicsUnit.Point);
|
||||
txtProxyPassword.Location = new System.Drawing.Point(163, 29);
|
||||
txtProxyPassword.Name = "txtProxyPassword";
|
||||
txtProxyPassword.PasswordChar = '*';
|
||||
txtProxyPassword.Size = new System.Drawing.Size(184, 22);
|
||||
txtProxyPassword.TabIndex = 3;
|
||||
txtProxyPassword.UseSystemPasswordChar = true;
|
||||
@@ -332,25 +333,25 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
pnlDefaultUpdate.Controls.Add(pnlProxy);
|
||||
pnlDefaultUpdate.Controls.Add(groupBoxReleaseChannel);
|
||||
pnlDefaultUpdate.Controls.Add(pnlUpdateCheck);
|
||||
pnlDefaultUpdate.Controls.Add(lblUpdateAdminInfo);
|
||||
pnlDefaultUpdate.Controls.Add(lblRegistrySettingsUsedInfo);
|
||||
pnlDefaultUpdate.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
pnlDefaultUpdate.Location = new System.Drawing.Point(0, 0);
|
||||
pnlDefaultUpdate.Name = "pnlDefaultUpdate";
|
||||
pnlDefaultUpdate.Size = new System.Drawing.Size(610, 483);
|
||||
pnlDefaultUpdate.TabIndex = 4;
|
||||
//
|
||||
// lblUpdateAdminInfo
|
||||
// lblRegistrySettingsUsedInfo
|
||||
//
|
||||
lblUpdateAdminInfo.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||
lblUpdateAdminInfo.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
lblUpdateAdminInfo.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
lblUpdateAdminInfo.Location = new System.Drawing.Point(0, 0);
|
||||
lblUpdateAdminInfo.Name = "lblUpdateAdminInfo";
|
||||
lblUpdateAdminInfo.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
lblUpdateAdminInfo.Size = new System.Drawing.Size(610, 30);
|
||||
lblUpdateAdminInfo.TabIndex = 0;
|
||||
lblUpdateAdminInfo.Text = "Some settings are configured by your Administrator. Please contact your administrator for more information.";
|
||||
lblUpdateAdminInfo.Visible = false;
|
||||
lblRegistrySettingsUsedInfo.BackColor = System.Drawing.SystemColors.ControlLight;
|
||||
lblRegistrySettingsUsedInfo.Dock = System.Windows.Forms.DockStyle.Top;
|
||||
lblRegistrySettingsUsedInfo.ForeColor = System.Drawing.SystemColors.ControlText;
|
||||
lblRegistrySettingsUsedInfo.Location = new System.Drawing.Point(0, 0);
|
||||
lblRegistrySettingsUsedInfo.Name = "lblRegistrySettingsUsedInfo";
|
||||
lblRegistrySettingsUsedInfo.Padding = new System.Windows.Forms.Padding(0, 2, 0, 0);
|
||||
lblRegistrySettingsUsedInfo.Size = new System.Drawing.Size(610, 30);
|
||||
lblRegistrySettingsUsedInfo.TabIndex = 0;
|
||||
lblRegistrySettingsUsedInfo.Text = "Some settings are configured by your Administrator. Please contact your administrator for more information.";
|
||||
lblRegistrySettingsUsedInfo.Visible = false;
|
||||
//
|
||||
// UpdatesPage
|
||||
//
|
||||
@@ -397,7 +398,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
private System.Windows.Forms.TableLayoutPanel tblProxyBasic;
|
||||
private System.Windows.Forms.TableLayoutPanel tblProxyAuthentication;
|
||||
private System.Windows.Forms.Panel pnlDefaultUpdate;
|
||||
internal System.Windows.Forms.Label lblUpdateAdminInfo;
|
||||
internal System.Windows.Forms.Label lblRegistrySettingsUsedInfo;
|
||||
internal MrngComboBox cboUpdateCheckFrequency;
|
||||
}
|
||||
}
|
||||
@@ -21,7 +21,6 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
private AppUpdater _appUpdate;
|
||||
private readonly OptRegistryUpdatesPage _RegistrySettings = new();
|
||||
private bool _pageEnabled = true;
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -62,69 +61,22 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
btnTestProxy.Text = Language.TestProxy;
|
||||
|
||||
lblUpdateAdminInfo.Text = Language.OptionsAdminInfo;
|
||||
lblRegistrySettingsUsedInfo.Text = Language.OptionsCompanyPolicyMessage;
|
||||
}
|
||||
|
||||
public override void LoadSettings()
|
||||
{
|
||||
// Checks the combination of the following registry settings:
|
||||
// 1. AllowCheckForUpdates is false.
|
||||
// 2. AllowCheckForUpdatesAutomatical and AllowCheckForUpdatesManual are false.
|
||||
// 3. Disable page and stop processing at this point.
|
||||
if (UpdatesForbidden())
|
||||
return;
|
||||
|
||||
chkCheckForUpdatesOnStartup.Checked = Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup;
|
||||
if (!_RegistrySettings.CheckForUpdatesFrequencyDays.IsKeyPresent)
|
||||
cboUpdateCheckFrequency.Enabled = chkCheckForUpdatesOnStartup.Checked;
|
||||
|
||||
if (CommonRegistrySettings.AllowCheckForUpdatesAutomatical)
|
||||
{
|
||||
cboUpdateCheckFrequency.Items.Clear();
|
||||
int nDaily = cboUpdateCheckFrequency.Items.Add(Language.Daily);
|
||||
int nWeekly = cboUpdateCheckFrequency.Items.Add(Language.Weekly);
|
||||
int nMonthly = cboUpdateCheckFrequency.Items.Add(Language.Monthly);
|
||||
if (Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays < 1)
|
||||
{
|
||||
chkCheckForUpdatesOnStartup.Checked = false;
|
||||
cboUpdateCheckFrequency.SelectedIndex = nDaily;
|
||||
} // Daily
|
||||
else
|
||||
{
|
||||
switch (Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays)
|
||||
{
|
||||
case 1:
|
||||
cboUpdateCheckFrequency.SelectedIndex = nDaily;
|
||||
break;
|
||||
case 7:
|
||||
cboUpdateCheckFrequency.SelectedIndex = nWeekly;
|
||||
break;
|
||||
case 31:
|
||||
cboUpdateCheckFrequency.SelectedIndex = nMonthly;
|
||||
break;
|
||||
default:
|
||||
int nCustom =
|
||||
cboUpdateCheckFrequency.Items.Add(string.Format(Language.UpdateFrequencyCustom, Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays));
|
||||
cboUpdateCheckFrequency.SelectedIndex = nCustom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int stable = cboReleaseChannel.Items.Add(UpdateChannelInfo.STABLE);
|
||||
int beta = cboReleaseChannel.Items.Add(UpdateChannelInfo.PREVIEW);
|
||||
int dev = cboReleaseChannel.Items.Add(UpdateChannelInfo.NIGHTLY);
|
||||
switch (Properties.OptionsUpdatesPage.Default.UpdateChannel)
|
||||
{
|
||||
case UpdateChannelInfo.STABLE:
|
||||
cboReleaseChannel.SelectedIndex = stable;
|
||||
break;
|
||||
case UpdateChannelInfo.PREVIEW:
|
||||
cboReleaseChannel.SelectedIndex = beta;
|
||||
break;
|
||||
case UpdateChannelInfo.NIGHTLY:
|
||||
cboReleaseChannel.SelectedIndex = dev;
|
||||
break;
|
||||
default:
|
||||
cboReleaseChannel.SelectedIndex = stable;
|
||||
break;
|
||||
}
|
||||
InitialiseCheckForUpdatesOnStartupComboBox();
|
||||
InitialiseReleaseChannelComboBox();
|
||||
|
||||
chkUseProxyForAutomaticUpdates.Checked = Properties.OptionsUpdatesPage.Default.UpdateUseProxy;
|
||||
tblProxyBasic.Enabled = Properties.OptionsUpdatesPage.Default.UpdateUseProxy;
|
||||
@@ -145,19 +97,29 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
{
|
||||
base.SaveSettings();
|
||||
|
||||
// Checks the combination of the following registry settings:
|
||||
// 1. AllowCheckForUpdates is false.
|
||||
// 2. AllowCheckForUpdatesAutomatical and AllowCheckForUpdatesManual are false.
|
||||
// 3. Disable page and stop processing at this point.
|
||||
if (UpdatesForbidden())
|
||||
return;
|
||||
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup = chkCheckForUpdatesOnStartup.Checked;
|
||||
if (cboUpdateCheckFrequency.SelectedItem.ToString() == Language.Daily)
|
||||
|
||||
string UpdateCheckFrequency = cboUpdateCheckFrequency.SelectedItem?.ToString();
|
||||
if (UpdateCheckFrequency == Language.Never)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup = false;
|
||||
}
|
||||
if (UpdateCheckFrequency == Language.Daily)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays = 1;
|
||||
}
|
||||
else if (cboUpdateCheckFrequency.SelectedItem.ToString() == Language.Weekly)
|
||||
else if (UpdateCheckFrequency == Language.Weekly)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays = 7;
|
||||
}
|
||||
else if (cboUpdateCheckFrequency.SelectedItem.ToString() == Language.Monthly)
|
||||
else if (UpdateCheckFrequency == Language.Monthly)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays = 31;
|
||||
}
|
||||
@@ -176,9 +138,16 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
public override void LoadRegistrySettings()
|
||||
{
|
||||
// Checks the combination of the following registry settings:
|
||||
// 1. AllowCheckForUpdates is false.
|
||||
// 2. AllowCheckForUpdatesAutomatical and AllowCheckForUpdatesManual are false.
|
||||
// 3. Disable page and stop processing at this point.
|
||||
if (UpdatesForbidden())
|
||||
return;
|
||||
|
||||
// AllowCheckForUpdatesAutomatical reg setting:
|
||||
// 1. Allowed/default: true; Disabled: false.
|
||||
// 2. Disable the option "check for updates on startup".
|
||||
if (!CommonRegistrySettings.AllowCheckForUpdatesAutomatical)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup = false;
|
||||
@@ -186,87 +155,134 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
DisableControl(cboUpdateCheckFrequency);
|
||||
}
|
||||
|
||||
if (_RegistrySettings.CheckForUpdatesFrequencyDays.IsKeyPresent && _RegistrySettings.CheckForUpdatesFrequencyDays.Value >= 1)
|
||||
// CheckForUpdatesFrequencyDays reg setting:
|
||||
// 1. Is 0 or less, than CheckForUpdatesOnStartup will be disabled.
|
||||
// 2. Is Valid than set CheckForUpdatesFrequencyDays option based on value.
|
||||
if (CommonRegistrySettings.AllowCheckForUpdatesAutomatical && _RegistrySettings.CheckForUpdatesFrequencyDays.IsSet)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays = _RegistrySettings.CheckForUpdatesFrequencyDays.Value;
|
||||
DisableControl(cboUpdateCheckFrequency);
|
||||
if (_RegistrySettings.CheckForUpdatesFrequencyDays.Value < 0)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup = false;
|
||||
DisableControl(chkCheckForUpdatesOnStartup);
|
||||
}
|
||||
else if (_RegistrySettings.CheckForUpdatesFrequencyDays.IsValid)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup = true;
|
||||
DisableControl(chkCheckForUpdatesOnStartup);
|
||||
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays = _RegistrySettings.CheckForUpdatesFrequencyDays.Value;
|
||||
DisableControl(cboUpdateCheckFrequency);
|
||||
}
|
||||
}
|
||||
|
||||
// Enable or disable the "Update Check" button if allowed or not.
|
||||
btnUpdateCheckNow.Enabled = CommonRegistrySettings.AllowCheckForUpdatesManual;
|
||||
|
||||
if (_RegistrySettings.UpdateChannel.IsKeyPresent)
|
||||
// UpdateChannel reg setting: set UpdateChannel option based on value
|
||||
if (_RegistrySettings.UpdateChannel.IsValid)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateChannel = _RegistrySettings.UpdateChannel.Value;
|
||||
DisableControl(cboReleaseChannel);
|
||||
}
|
||||
|
||||
if (_RegistrySettings.UseProxyForUpdates.IsKeyPresent)
|
||||
// UseProxyForUpdates reg setting: set UseProxyForUpdates option based on value
|
||||
// 1. Continues with the options checks for "ProxyAddress" and "ProxyPort"
|
||||
// 2. Moved on to the "UseProxyAuthentication" options if true
|
||||
if (_RegistrySettings.UseProxyForUpdates.IsSet)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateUseProxy = _RegistrySettings.UseProxyForUpdates.Value;
|
||||
bool UseProxy = _RegistrySettings.UseProxyForUpdates.Value;
|
||||
Properties.OptionsUpdatesPage.Default.UpdateUseProxy = UseProxy;
|
||||
DisableControl(chkUseProxyForAutomaticUpdates);
|
||||
|
||||
if (_RegistrySettings.UseProxyForUpdates.Value == false)
|
||||
// If the proxy is not used, reset the proxy address, port, and authentication settings to defaults.
|
||||
if (!UseProxy)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyAddress = "";
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyPort = 80;
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyUseAuthentication = false;
|
||||
}
|
||||
|
||||
if (_RegistrySettings.ProxyAddress.IsKeyPresent && _RegistrySettings.UseProxyForUpdates.Value == true)
|
||||
// ProxyAddress reg setting: set ProxyAddress option based on value
|
||||
if (_RegistrySettings.ProxyAddress.IsSet && UseProxy)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyAddress = _RegistrySettings.ProxyAddress.Value;
|
||||
DisableControl(txtProxyAddress);
|
||||
}
|
||||
|
||||
if (_RegistrySettings.ProxyPort.IsKeyPresent && _RegistrySettings.UseProxyForUpdates.Value == true)
|
||||
// ProxyPort reg setting: set ProxyPort option based on value
|
||||
if (_RegistrySettings.ProxyPort.IsSet && UseProxy)
|
||||
{
|
||||
// only set value if not is 0 to prevent errors..
|
||||
if (_RegistrySettings.ProxyPort.Value >= 1)
|
||||
_RegistrySettings.ProxyPort.SetValidation((int)numProxyPort.Minimum, (int)numProxyPort.Maximum);
|
||||
if (_RegistrySettings.ProxyPort.IsValid)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyPort = _RegistrySettings.ProxyPort.Value;
|
||||
|
||||
DisableControl(numProxyPort);
|
||||
DisableControl(numProxyPort);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (_RegistrySettings.UseProxyAuthentication.IsKeyPresent)
|
||||
// UseProxyAuthentication reg setting: set UseProxyAuthentication option based on value
|
||||
// 1. Only applied when UpdateUseProxy is true
|
||||
// 2. Continues with the options checks for "ProxyAuthUser" and "ProxyAuthPass"
|
||||
if (Properties.OptionsUpdatesPage.Default.UpdateUseProxy && _RegistrySettings.UseProxyAuthentication.IsSet)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyUseAuthentication = _RegistrySettings.UseProxyAuthentication.Value;
|
||||
bool UseProxyAuth = _RegistrySettings.UseProxyAuthentication.Value;
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyUseAuthentication = UseProxyAuth;
|
||||
DisableControl(chkUseProxyAuthentication);
|
||||
|
||||
if (_RegistrySettings.UseProxyAuthentication.Value == false)
|
||||
// If proxy authentication is not used, reset the proxy authentication username and password to defaults.
|
||||
if (!UseProxyAuth)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyAuthUser = "";
|
||||
//Properties.OptionsUpdatesPage.Default.UpdateProxyAuthPass = "";
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyAuthPass = "";
|
||||
}
|
||||
|
||||
if (_RegistrySettings.ProxyAuthUser.IsKeyPresent && _RegistrySettings.UseProxyAuthentication.Value == true)
|
||||
// ProxyAuthUser reg setting: set ProxyAuthUser option based on value
|
||||
if (_RegistrySettings.ProxyAuthUser.IsSet && UseProxyAuth)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyAuthUser = _RegistrySettings.ProxyAuthUser.Value;
|
||||
DisableControl(txtProxyUsername);
|
||||
}
|
||||
|
||||
/*if (_RegistrySettings.ProxyAuthPass.IsProvided && _RegistrySettings.UseProxyAuthentication.Value == true)
|
||||
// ProxyAuthPass reg setting:
|
||||
// 1. Test decription works to prevents potential issues
|
||||
// 2. Set ProxyAuthPass option based on value
|
||||
if (_RegistrySettings.ProxyAuthPass.IsSet && UseProxyAuth)
|
||||
{
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyAuthPass = _RegistrySettings.ProxyAuthPass;
|
||||
DisableControl(txtProxyPassword);
|
||||
}*/
|
||||
// Prevents potential issues when using UpdateProxyAuthPass later.
|
||||
try
|
||||
{
|
||||
LegacyRijndaelCryptographyProvider cryptographyProvider = new();
|
||||
string decryptedPassword;
|
||||
string ProxyAuthPass = _RegistrySettings.ProxyAuthPass.Value;
|
||||
decryptedPassword = cryptographyProvider.Decrypt(ProxyAuthPass, Runtime.EncryptionKey);
|
||||
|
||||
Properties.OptionsUpdatesPage.Default.UpdateProxyAuthPass = ProxyAuthPass;
|
||||
DisableControl(txtProxyPassword);
|
||||
}
|
||||
catch
|
||||
{
|
||||
// Fire-and-forget: The password in the registry is not encrypted.
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
lblUpdateAdminInfo.Visible = ShowAdministratorInfo();
|
||||
// Updates the visibility of the information label indicating whether registry settings are used.
|
||||
lblRegistrySettingsUsedInfo.Visible = ShowRegistrySettingsUsedInfo();
|
||||
}
|
||||
|
||||
public override bool ShowAdministratorInfo()
|
||||
public override bool ShowRegistrySettingsUsedInfo()
|
||||
{
|
||||
return !CommonRegistrySettings.AllowCheckForUpdatesAutomatical
|
||||
|| !CommonRegistrySettings.AllowCheckForUpdatesManual
|
||||
|| _RegistrySettings.CheckForUpdatesFrequencyDays.IsKeyPresent
|
||||
|| _RegistrySettings.UpdateChannel.IsKeyPresent
|
||||
|| _RegistrySettings.UseProxyForUpdates.IsKeyPresent
|
||||
|| _RegistrySettings.ProxyAddress.IsKeyPresent
|
||||
|| _RegistrySettings.ProxyPort.IsKeyPresent
|
||||
|| _RegistrySettings.UseProxyAuthentication.IsKeyPresent
|
||||
|| _RegistrySettings.ProxyAuthUser.IsKeyPresent;
|
||||
|| _RegistrySettings.CheckForUpdatesFrequencyDays.IsSet
|
||||
|| _RegistrySettings.UpdateChannel.IsValid
|
||||
|| _RegistrySettings.UseProxyForUpdates.IsSet
|
||||
|| _RegistrySettings.ProxyAddress.IsSet
|
||||
|| _RegistrySettings.ProxyPort.IsValid
|
||||
|| _RegistrySettings.UseProxyAuthentication.IsSet
|
||||
|| _RegistrySettings.ProxyAuthUser.IsSet
|
||||
|| _RegistrySettings.ProxyAuthPass.IsSet;
|
||||
}
|
||||
|
||||
#endregion
|
||||
@@ -275,8 +291,10 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
private void chkCheckForUpdatesOnStartup_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (!_RegistrySettings.CheckForUpdatesFrequencyDays.IsKeyPresent)
|
||||
if (!_RegistrySettings.CheckForUpdatesFrequencyDays.IsValid)
|
||||
cboUpdateCheckFrequency.Enabled = chkCheckForUpdatesOnStartup.Checked;
|
||||
|
||||
InitialiseCheckForUpdatesOnStartupComboBox();
|
||||
}
|
||||
|
||||
private void btnUpdateCheckNow_Click(object sender, EventArgs e)
|
||||
@@ -286,24 +304,16 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
|
||||
private void chkUseProxyForAutomaticUpdates_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
tblProxyBasic.Enabled = chkUseProxyForAutomaticUpdates.Checked;
|
||||
btnTestProxy.Enabled = chkUseProxyForAutomaticUpdates.Checked;
|
||||
// Enables/disables proxy settings controls
|
||||
bool useProxy = chkUseProxyForAutomaticUpdates.Checked;
|
||||
tblProxyBasic.Enabled = useProxy;
|
||||
btnTestProxy.Enabled = useProxy;
|
||||
|
||||
if (chkUseProxyForAutomaticUpdates.Checked)
|
||||
{
|
||||
if (!_RegistrySettings.UseProxyForUpdates.IsKeyPresent)
|
||||
chkUseProxyAuthentication.Enabled = true;
|
||||
|
||||
if (chkUseProxyAuthentication.Checked && !_RegistrySettings.UseProxyAuthentication.IsKeyPresent)
|
||||
{
|
||||
tblProxyAuthentication.Enabled = true;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
chkUseProxyAuthentication.Enabled = false;
|
||||
tblProxyAuthentication.Enabled = false;
|
||||
}
|
||||
// Enables/disables proxy authentication controls
|
||||
bool useProxyAuth = chkUseProxyAuthentication.Checked;
|
||||
bool useProxyAuthRegIsSet = _RegistrySettings.UseProxyAuthentication.IsSet;
|
||||
chkUseProxyAuthentication.Enabled = useProxy && !useProxyAuthRegIsSet;
|
||||
tblProxyAuthentication.Enabled = useProxy && useProxyAuth && !useProxyAuthRegIsSet;
|
||||
}
|
||||
|
||||
private async void btnTestProxy_Click(object sender, EventArgs e)
|
||||
@@ -348,23 +358,116 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
private void chkUseProxyAuthentication_CheckedChanged(object sender, EventArgs e)
|
||||
{
|
||||
if (chkUseProxyForAutomaticUpdates.Checked)
|
||||
{
|
||||
tblProxyAuthentication.Enabled = chkUseProxyAuthentication.Checked;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region Private Methods
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the update check frequency ComboBox.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Clears existing items, adds default options (Daily, Weekly, Monthly), and sets the selected option
|
||||
/// based on the saved frequency. If the saved frequency is less than 1, adds and selects "Never".
|
||||
/// </remarks>
|
||||
private void InitialiseCheckForUpdatesOnStartupComboBox()
|
||||
{
|
||||
cboUpdateCheckFrequency.Items.Clear();
|
||||
int nDaily = cboUpdateCheckFrequency.Items.Add(Language.Daily);
|
||||
int nWeekly = cboUpdateCheckFrequency.Items.Add(Language.Weekly);
|
||||
int nMonthly = cboUpdateCheckFrequency.Items.Add(Language.Monthly);
|
||||
if (Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays < 1)
|
||||
{
|
||||
chkCheckForUpdatesOnStartup.Checked = false;
|
||||
Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup = false;
|
||||
|
||||
int nNever = cboUpdateCheckFrequency.Items.Add(Language.Never);
|
||||
cboUpdateCheckFrequency.SelectedIndex = nNever;
|
||||
}
|
||||
else if (!chkCheckForUpdatesOnStartup.Checked)
|
||||
{
|
||||
int nNever = cboUpdateCheckFrequency.Items.Add(Language.Never);
|
||||
cboUpdateCheckFrequency.SelectedIndex = nNever;
|
||||
}
|
||||
else
|
||||
{
|
||||
switch (Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays)
|
||||
{
|
||||
case 1:
|
||||
cboUpdateCheckFrequency.SelectedIndex = nDaily;
|
||||
break;
|
||||
case 7:
|
||||
cboUpdateCheckFrequency.SelectedIndex = nWeekly;
|
||||
break;
|
||||
case 31:
|
||||
cboUpdateCheckFrequency.SelectedIndex = nMonthly;
|
||||
break;
|
||||
default:
|
||||
int nCustom =
|
||||
cboUpdateCheckFrequency.Items.Add(string.Format(Language.UpdateFrequencyCustom, Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays));
|
||||
cboUpdateCheckFrequency.SelectedIndex = nCustom;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// Initializes the release channel ComboBox
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// Set available options (STABLE, PREVIEW, NIGHTLY) and selects the appropriate channel based on saved settings
|
||||
/// </remarks>
|
||||
private void InitialiseReleaseChannelComboBox()
|
||||
{
|
||||
cboReleaseChannel.Items.Clear();
|
||||
int stable = cboReleaseChannel.Items.Add(UpdateChannelInfo.STABLE);
|
||||
int beta = cboReleaseChannel.Items.Add(UpdateChannelInfo.PREVIEW);
|
||||
int dev = cboReleaseChannel.Items.Add(UpdateChannelInfo.NIGHTLY);
|
||||
cboReleaseChannel.SelectedIndex = Properties.OptionsUpdatesPage.Default.UpdateChannel switch
|
||||
{
|
||||
UpdateChannelInfo.STABLE => stable,
|
||||
UpdateChannelInfo.PREVIEW => beta,
|
||||
UpdateChannelInfo.NIGHTLY => dev,
|
||||
_ => stable,
|
||||
};
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Determines if updates are forbidden based on registry settings.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// True if updates are forbidden; otherwise, false.
|
||||
/// </returns>
|
||||
private bool UpdatesForbidden()
|
||||
{
|
||||
bool forbidden = !CommonRegistrySettings.AllowCheckForUpdates
|
||||
bool disablePage = !CommonRegistrySettings.AllowCheckForUpdates
|
||||
|| (!CommonRegistrySettings.AllowCheckForUpdatesAutomatical
|
||||
&& !CommonRegistrySettings.AllowCheckForUpdatesManual);
|
||||
|
||||
if (forbidden && _pageEnabled)
|
||||
if (disablePage)
|
||||
{
|
||||
DisablePage();
|
||||
|
||||
return forbidden;
|
||||
// Ensure the UI (CheckFrequency ComboBox) appears correct when disabled
|
||||
cboUpdateCheckFrequency.Items.Clear();
|
||||
int nNever = cboUpdateCheckFrequency.Items.Add(Language.Never);
|
||||
cboUpdateCheckFrequency.SelectedIndex = nNever;
|
||||
|
||||
// Ensure the UI (ReleaseChannel ComboBox) appears correct when disabled
|
||||
cboReleaseChannel.Items.Clear();
|
||||
int stable = cboReleaseChannel.Items.Add(UpdateChannelInfo.STABLE);
|
||||
cboReleaseChannel.SelectedIndex = stable;
|
||||
}
|
||||
|
||||
return disablePage;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Disables all controls on the page related to update settings and proxy configurations.
|
||||
/// </summary>
|
||||
public override void DisablePage()
|
||||
{
|
||||
chkCheckForUpdatesOnStartup.Checked = false;
|
||||
@@ -391,9 +494,7 @@ namespace mRemoteNG.UI.Forms.OptionsPages
|
||||
txtProxyPassword.ReadOnly = true;
|
||||
btnTestProxy.Enabled = false;
|
||||
|
||||
lblUpdateAdminInfo.Visible = true;
|
||||
|
||||
_pageEnabled = false;
|
||||
lblRegistrySettingsUsedInfo.Visible = true;
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
@@ -117,7 +117,4 @@
|
||||
<resheader name="writer">
|
||||
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
|
||||
</resheader>
|
||||
<metadata name="lblUpdateAdminInfo.Locked" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">
|
||||
<value>True</value>
|
||||
</metadata>
|
||||
</root>
|
||||
@@ -377,6 +377,7 @@ namespace mRemoteNG.UI.Forms
|
||||
if (!CommonRegistrySettings.AllowCheckForUpdatesAutomatical) return;
|
||||
|
||||
if (!Properties.OptionsUpdatesPage.Default.CheckForUpdatesOnStartup) return;
|
||||
if (Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays == 0) return;
|
||||
|
||||
DateTime nextUpdateCheck =
|
||||
Convert.ToDateTime(Properties.OptionsUpdatesPage.Default.CheckForUpdatesLastCheck.Add(TimeSpan.FromDays(Convert.ToDouble(Properties.OptionsUpdatesPage.Default.CheckForUpdatesFrequencyDays))));
|
||||
|
||||
@@ -0,0 +1,248 @@
|
||||
|
||||
using Microsoft.Win32;
|
||||
using NUnit.Framework.Internal;
|
||||
using System.Runtime.Versioning;
|
||||
using System;
|
||||
using NUnit.Framework;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry.RegistryEntryTest
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class BaseRegistryEntryTest
|
||||
{
|
||||
private const string TestRoot = @"Software\mRemoteNGTest";
|
||||
private const RegistryHive TestHive = RegistryHive.CurrentUser;
|
||||
private const string TestPath = $"{TestRoot}\\EntryTests";
|
||||
|
||||
[Test]
|
||||
public void Path_SetValidValue_GetReturnsSameValue()
|
||||
{
|
||||
string expectedPath = @"SOFTWARE\Microsoft";
|
||||
var entry = new WinRegistryEntry<string>
|
||||
{
|
||||
Path = expectedPath
|
||||
};
|
||||
Assert.That(expectedPath, Is.EqualTo(entry.Path));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Path_SetNullValue_ThrowsArgumentNullException()
|
||||
{
|
||||
var entry = new WinRegistryEntry<string>();
|
||||
Assert.Throws<ArgumentNullException>(() => entry.Path = null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Name_SetValidValue_GetReturnsSameValue()
|
||||
{
|
||||
string expectedName = "Version";
|
||||
var entry = new WinRegistryEntry<string>
|
||||
{
|
||||
Name = expectedName
|
||||
};
|
||||
Assert.That(expectedName, Is.EqualTo(entry.Name));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Value_SetValidValue_GetReturnsSameValue()
|
||||
{
|
||||
string expectedValue = "1.0";
|
||||
var entry = new WinRegistryEntry<string>
|
||||
{
|
||||
Value = expectedValue
|
||||
};
|
||||
Assert.That(expectedValue, Is.EqualTo(entry.Value));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ValueKind_SetInvalidValue_ThrowsArgumentException()
|
||||
{
|
||||
var entry = new WinRegistryEntry<string>();
|
||||
Assert.Throws<ArgumentException>(() => entry.SetValueKind((RegistryValueKind)100));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsSet_ValueHasBeenSet_NotRead_ReturnsFalse()
|
||||
{
|
||||
var entry = new WinRegistryEntry<string>
|
||||
{
|
||||
Value = "Test"
|
||||
};
|
||||
Assert.That(entry.IsSet, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsKeyReadable_AllPropertiesSet_ReturnsTrue()
|
||||
{
|
||||
var entry = new WinRegistryEntry<string>
|
||||
{
|
||||
Hive = RegistryHive.LocalMachine,
|
||||
Path = @"SOFTWARE\Microsoft",
|
||||
Name = "Version"
|
||||
};
|
||||
Assert.That(entry.IsReadable, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsKeyWritable_AllPropertiesSet_ReturnsTrue()
|
||||
{
|
||||
var entry = new WinRegistryEntry<string>
|
||||
{
|
||||
Hive = RegistryHive.LocalMachine,
|
||||
Path = @"SOFTWARE\Microsoft",
|
||||
Name = "Version",
|
||||
Value = "1.0"
|
||||
};
|
||||
Assert.That(entry.IsWritable, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Read_WhenRegistryKeyIsNull_ThrowsInvalidOperationException()
|
||||
{
|
||||
var entry = new WinRegistryEntry<string>();
|
||||
Assert.Throws<InvalidOperationException>(() => entry.Read());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Write_WhenKeyIsUnwritable_ThrowsInvalidOperationException()
|
||||
{
|
||||
var entry = new WinRegistryEntry<string>
|
||||
{
|
||||
Name = "Version"
|
||||
};
|
||||
Assert.Throws<InvalidOperationException>(() => entry.Write());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteDefaultAndReadDefault_Entry_DoesNotThrowAndReadsCorrectly()
|
||||
{
|
||||
var entry = new WinRegistryEntry<int>(TestHive, TestPath, 0)
|
||||
{
|
||||
Hive = TestHive,
|
||||
Path = TestPath,
|
||||
Value = 0,
|
||||
};
|
||||
|
||||
var readEntry = new WinRegistryEntry<int>
|
||||
{
|
||||
Hive = TestHive,
|
||||
Path = TestPath,
|
||||
};
|
||||
|
||||
Assert.That(() => entry.Write(), Throws.Nothing);
|
||||
Assert.That(() => readEntry.Read(), Throws.Nothing);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(readEntry.ValueKind, Is.EqualTo(RegistryValueKind.String));
|
||||
Assert.That(readEntry.Value, Is.EqualTo(entry.Value));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WriteAndRead_Entry_DoesNotThrowAndReadsCorrectly()
|
||||
{
|
||||
var entry = new WinRegistryEntry<long>
|
||||
{
|
||||
Hive = TestHive,
|
||||
Path = TestPath,
|
||||
Name = "TestRead",
|
||||
Value = 200
|
||||
};
|
||||
|
||||
var readEntry = new WinRegistryEntry<long>
|
||||
{
|
||||
Hive = TestHive,
|
||||
Path = TestPath,
|
||||
Name = "TestRead"
|
||||
};
|
||||
|
||||
Assert.That(() => entry.Write(), Throws.Nothing);
|
||||
Assert.That(() => readEntry.Read(), Throws.Nothing);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(readEntry.ValueKind, Is.EqualTo(entry.ValueKind));
|
||||
Assert.That(readEntry.Value, Is.EqualTo(entry.Value));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FluentWriteAndRead_DoesNotThrow_ReturnsStrJustATest()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "FluentReadAndWriteTest", "JustATest").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "FluentReadAndWriteTest").Read();
|
||||
Assert.That(entry.Value, Is.EqualTo("JustATest"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FluentWriteReadAndChange_DoesNotThrow_WriteReadsCorrectly()
|
||||
{
|
||||
var entry = WinRegistryEntry<string>
|
||||
.New(TestHive, TestPath, "FluentReadWriteAndChangeTest", "JustASecondTest")
|
||||
.Write()
|
||||
.Read();
|
||||
string result1 = entry.Value;
|
||||
|
||||
string result2 = entry
|
||||
.Write("JustAChangeTest")
|
||||
.Read()
|
||||
.Value;
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(result1, Is.EqualTo("JustASecondTest"));
|
||||
Assert.That(result2, Is.EqualTo("JustAChangeTest"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Read_LockAfter_IsLocked()
|
||||
{
|
||||
var entry = WinRegistryEntry<string>
|
||||
.New(TestHive, TestPath, "IsLockedAfter", "After")
|
||||
.Write()
|
||||
.Read()
|
||||
.Lock();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entry.IsLocked, Is.EqualTo(true));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Read_LockBevore_IsLocked()
|
||||
{
|
||||
var entry = WinRegistryEntry<string>
|
||||
.New(TestHive, TestPath, "IsLockedBevore", "Bevore")
|
||||
.Write()
|
||||
.Read()
|
||||
.Lock();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entry.IsLocked, Is.EqualTo(true));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Read_Lock_ThrowWhenRead()
|
||||
{
|
||||
var entry = WinRegistryEntry<string>
|
||||
.New(TestHive, TestPath, "ReadLockThrow", "ReadingIsLocked")
|
||||
.Write()
|
||||
.Read()
|
||||
.Lock();
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => entry.Read());
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
// Delete all created tests
|
||||
WinRegistry winReg = new();
|
||||
winReg.DeleteTree(TestHive, TestRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
|
||||
using Microsoft.Win32;
|
||||
using NUnit.Framework.Internal;
|
||||
using System.Runtime.Versioning;
|
||||
using NUnit.Framework;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry.RegistryEntryTest
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class BoolEntryTest
|
||||
{
|
||||
private const string TestRoot = @"Software\mRemoteNGTest";
|
||||
private const RegistryHive TestHive = RegistryHive.CurrentUser;
|
||||
private const string TestPath = $"{TestRoot}\\BoolEntryTest";
|
||||
|
||||
[Test]
|
||||
public void StringTrue_SuccessfulToBool_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<bool>.New(TestHive, TestPath, "IsTrueString", true).Write());
|
||||
var entry = WinRegistryEntry<bool>.New(TestHive, TestPath, "IsTrueString").Read();
|
||||
Assert.That(entry.Value, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void StringFalse_SuccessfulToBool_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<bool>.New(TestHive, TestPath, "IsFalseString", false).Write());
|
||||
|
||||
var entry = WinRegistryEntry<bool>.New(TestHive, TestPath, "IsFalseString");
|
||||
entry.Value = true; // change Value to true to ensure a value was readed
|
||||
entry.Read();
|
||||
|
||||
Assert.That(entry.Value, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DWordTrue_SuccessfulToBool_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<bool>.New(TestHive, TestPath, "IsTrueDword", true).SetValueKind(RegistryValueKind.DWord).Write());
|
||||
var entry = WinRegistryEntry<bool>.New(TestHive, TestPath, "IsTrueDword").Read();
|
||||
Assert.That(entry.Value, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void DWordFalse_SuccessfulToBool_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<bool>.New(TestHive, TestPath, "IsFalseDword", false).SetValueKind(RegistryValueKind.DWord).Write());
|
||||
var entry = WinRegistryEntry<bool>.New(TestHive, TestPath, "IsFalseDword");
|
||||
entry.Value = true; // change Value to true to ensure a value was readed
|
||||
entry.Read();
|
||||
Assert.That(entry.Value, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FluentWrite_And_Read_DoesNotThrow_ReturnsBoolFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<bool>.New(TestHive, TestPath, "FluentReadAndWriteTest", false).SetValueKind(RegistryValueKind.DWord).Write());
|
||||
var entry = WinRegistryEntry<bool>.New(TestHive, TestPath, "FluentReadAndWriteTest", true).Read();
|
||||
Assert.That(entry.Value, Is.False);
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
// Delete all created tests
|
||||
WinRegistry winReg = new();
|
||||
winReg.DeleteTree(TestHive, TestRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,133 @@
|
||||
|
||||
using Microsoft.Win32;
|
||||
using NUnit.Framework.Internal;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using NUnit.Framework;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry.RegistryEntryTest
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class IntegerEntryTest
|
||||
{
|
||||
private const string TestRoot = @"Software\mRemoteNGTest";
|
||||
private const RegistryHive TestHive = RegistryHive.CurrentUser;
|
||||
private const string TestPath = $"{TestRoot}\\IntegerEntryTest";
|
||||
|
||||
public enum TestEnum
|
||||
{
|
||||
First = 1,
|
||||
Second = 2,
|
||||
Third = 3
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_NoValidationSet_EntryComplete_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 1).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid").Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_AllowedValuesSet_ValueInAllowedValues_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 2).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid").SetValidation(new int[] { 1, 2, 3 }).Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_AllowedValuesSet_ValueNotInAllowedValues_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 4).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid").SetValidation(new int[] { 1, 2, 3 }).Read();
|
||||
Assert.That(entry.IsValid, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_RangeSet_ValueInRange_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 5).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid").SetValidation(1,10).Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_RangeSet_ValueOutOfRange_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 50).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid").SetValidation(1, 10).Read();
|
||||
Assert.That(entry.IsValid, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_RangeSet_Value0_ValueOutOfRange_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValidZero", 0).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValidZero").SetValidation(0, 10).Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_RangeSet_DefaultMin_ValueInRange_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValidDefMin", 10).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValidDefMin").SetValidation("*", "10").Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_RangeSet_DefaultMax_ValueInRange_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValidDefMax", 1000).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValidDefMax").SetValidation("50", "*").Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_EnumSet_ValueInEnum_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 2).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid").SetValidation<TestEnum>().Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_EnumSet_ValueNotInEnum_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 5).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid").SetValidation<TestEnum>().Read();
|
||||
Assert.That(entry.IsValid, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_InvalidValueKind_ThrowArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", 5).SetValueKind(RegistryValueKind.Unknown));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Value_SetToNegativeNumber_ThrowArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => WinRegistryEntry<int>.New(TestHive, TestPath, "IsValid", -100));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FluentWrite_And_Read_DoesNotThrow_ReturnsInt12()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<int>.New(TestHive, TestPath, "FluentReadAndWriteTest", 12).Write());
|
||||
var entry = WinRegistryEntry<int>.New(TestHive, TestPath, "FluentReadAndWriteTest", 42).Read();
|
||||
Assert.That(entry.Value, Is.EqualTo(12));
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
// Delete all created tests
|
||||
WinRegistry winReg = new();
|
||||
winReg.DeleteTree(TestHive, TestPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
using Microsoft.Win32;
|
||||
using NUnit.Framework.Internal;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using NUnit.Framework;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry.RegistryEntryTest
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class LongIntegerEntryTest
|
||||
{
|
||||
private const string TestRoot = @"Software\mRemoteNGTest";
|
||||
private const RegistryHive TestHive = RegistryHive.CurrentUser;
|
||||
private const string TestPath = $"{TestRoot}\\LongIntegerEntryTest";
|
||||
|
||||
[Test]
|
||||
public void IsValid_NoValidationSet_EntryComplete_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid", 3047483647).Write());
|
||||
var entry = WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid").Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_AllowedValuesSet_ValueInAllowedValues_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid", 2147483649).Write());
|
||||
var entry = WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid").SetValidation(new long[] { 2147483648, 2147483649, 2147483650 }).Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_AllowedValuesSet_ValueNotInAllowedValues_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid", 4).Write());
|
||||
var entry = WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid").SetValidation(new long[] { 2147483648, 2147483649, 2147483650 }).Read();
|
||||
Assert.That(entry.IsValid, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_RangeSet_ValueInRange_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid", 2147483652).Write());
|
||||
var entry = WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid").SetValidation(2147483647, 2200000000).Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_RangeSet_ValueOutOfRange_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid", 20).Write());
|
||||
var entry = WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid").SetValidation(2147483647, 2200000000).Read();
|
||||
Assert.That(entry.IsValid, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_InvalidValueKind_ThrowArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid", 5).SetValueKind(RegistryValueKind.Unknown));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void Value_SetToNegativeNumber_ThrowArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => WinRegistryEntry<long>.New(TestHive, TestPath, "IsValid", -100));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FluentWrite_And_Read_DoesNotThrow_ReturnsLong15()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<long>.New(TestHive, TestPath, "FluentReadAndWriteTest", 15).Write());
|
||||
var entry = WinRegistryEntry<long>.New(TestHive, TestPath, "FluentReadAndWriteTest", 42).Read();
|
||||
Assert.That(entry.Value, Is.EqualTo(15));
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
// Delete all created tests
|
||||
WinRegistry winReg = new();
|
||||
winReg.DeleteTree(TestHive, TestRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,112 @@
|
||||
|
||||
using Microsoft.Win32;
|
||||
using NUnit.Framework.Internal;
|
||||
using System;
|
||||
using System.Runtime.Versioning;
|
||||
using NUnit.Framework;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry.RegistryEntryTest
|
||||
{
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class StringEntryTest
|
||||
{
|
||||
private const string TestRoot = @"Software\mRemoteNGTest";
|
||||
private const RegistryHive TestHive = RegistryHive.CurrentUser;
|
||||
private const string TestPath = $"{TestRoot}\\StringEntryTest";
|
||||
|
||||
public enum TestEnum
|
||||
{
|
||||
First = 1,
|
||||
Second = 2,
|
||||
Third = 3
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_NoValidationSet_EntryComplete_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "IsValid", "IsValid").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "IsValid").Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_AllowedValuesSet_ValueInAllowedValues_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "ArrayIsValid", "Banana").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "ArrayIsValid").SetValidation(new string[] { "Banana", "Strawberry", "Apple" }).Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_AllowedValuesSet_ValueNotInAllowedValues_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "ArrayIsInValid", "Cheese").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "ArrayIsInValid").SetValidation(new string[] { "Banana", "Strawberry", "Apple" }).Read();
|
||||
Assert.That(entry.IsValid, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_AllowedValuesSet_CorrectsValueSpellingAndValidatesSuccessfully()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "ArrayCorrectsSpellingIsValid", "StrawBerry").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "ArrayCorrectsSpellingIsValid").SetValidation(new string[] { "Banana", "Strawberry", "Apple" }).Read();
|
||||
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
Assert.That(entry.Value, Is.EqualTo("Strawberry"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_EnumSet_ValueInEnum_ReturnsTrue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "IsValid", "Second").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "IsValid").SetValidation<TestEnum>().Read();
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_EnumSet_ValueNotInEnum_ReturnsFalse()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "IsInValid", "Fourth").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "IsInValid").SetValidation<TestEnum>().Read();
|
||||
Assert.That(entry.IsValid, Is.False);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_EnumSet_CorrectsValueSpellingAndValidatesSuccessfully()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "IsValidCorrectsSpelling", "SecOND").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "IsValidCorrectsSpelling").SetValidation<TestEnum>().Read();
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entry.IsValid, Is.True);
|
||||
Assert.That(entry.Value, Is.EqualTo("Second"));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void IsValid_InvalidValueKind_ThrowArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => WinRegistryEntry<string>.New(TestHive, TestPath, "IsValid", "Windows").SetValueKind(RegistryValueKind.Unknown));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FluentWrite_And_Read_DoesNotThrow_ReturnsStrJustATest()
|
||||
{
|
||||
Assert.DoesNotThrow(() => WinRegistryEntry<string>.New(TestHive, TestPath, "FluentReadAndWriteTest", "JustATest").Write());
|
||||
var entry = WinRegistryEntry<string>.New(TestHive, TestPath, "FluentReadAndWriteTest", "TestFailed").Read();
|
||||
Assert.That(entry.Value, Is.EqualTo("JustATest"));
|
||||
}
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
// Delete all created tests
|
||||
WinRegistry winReg = new();
|
||||
winReg.DeleteTree(TestHive, TestRoot);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,188 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry
|
||||
{
|
||||
internal class WindowsRegistryAdvancedTests : WindowsRegistryAdvanced
|
||||
{
|
||||
private const string _TestRootKey = @"Software\mRemoteNGTest";
|
||||
private const RegistryHive _TestHive = RegistryHive.CurrentUser;
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
// GetBoolean && GetBoolValue (GetBoolValue -> Not Advanced but not tested jet)
|
||||
SetRegistryValue(_TestHive, _TestRootKey, "TestBoolAsString", "true", RegistryValueKind.String);
|
||||
SetRegistryValue(_TestHive, _TestRootKey, "TestBoolAsDWord", 0, RegistryValueKind.DWord);
|
||||
|
||||
// GetInteger Tests
|
||||
SetRegistryValue(_TestHive, _TestRootKey, "TestInteger", "4711", RegistryValueKind.DWord);
|
||||
|
||||
// GetString Tests
|
||||
SetRegistryValue(_TestHive, _TestRootKey, "TestString1", "Banane", RegistryValueKind.String);
|
||||
SetRegistryValue(_TestHive, _TestRootKey, "TestString2", "Hund", RegistryValueKind.String);
|
||||
}
|
||||
|
||||
[TearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
// Delete the registry keys here
|
||||
DeleteRegistryKey(_TestHive, _TestRootKey, true);
|
||||
}
|
||||
|
||||
#region GetBoolean() Tests
|
||||
// Non object returns
|
||||
[Test]
|
||||
public void GetBooleanFromString_ReturnsTrue()
|
||||
{
|
||||
var key = GetBoolean(_TestHive, _TestRootKey, "TestBoolAsString");
|
||||
Assert.That(key.Value, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
|
||||
[Test]
|
||||
public void GetBooleanFromDword_ReturnsFalse()
|
||||
{
|
||||
var key = GetBoolean(_TestHive, _TestRootKey, "TestBoolAsDWord");
|
||||
Assert.That(key.Value, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBooleanNotProvided_ReturnsDefaultTrue()
|
||||
{
|
||||
var key = GetBoolean(_TestHive, _TestRootKey, "TestBoolNotProvided", true);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo(true), "Value should be the default (true)");
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(false), "IsProvided should be false");
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetBoolValue()___No Object, just bool value returns
|
||||
[Test]
|
||||
public void GetBoolValueFromString_ReturnsTrue()
|
||||
{
|
||||
var key = GetBoolValue(_TestHive, _TestRootKey, "TestBoolAsString");
|
||||
Assert.That(key, Is.EqualTo(true));
|
||||
}
|
||||
[Test]
|
||||
public void GetBoolValueFromDword_ReturnsFalse()
|
||||
{
|
||||
var key = GetBoolValue(_TestHive, _TestRootKey, "TestBoolAsDWord", true);
|
||||
Assert.That(key, Is.EqualTo(false));
|
||||
}
|
||||
[Test]
|
||||
public void GetBoolValue_ReturnsDefaultTrue()
|
||||
{
|
||||
var key = GetBoolValue(_TestHive, _TestRootKey, "TestBoolNotProvided", true);
|
||||
Assert.That(key, Is.EqualTo(true));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetInteger()
|
||||
[Test]
|
||||
public void GetInteger()
|
||||
{
|
||||
var key = GetInteger(_TestHive, _TestRootKey, "TestInteger");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo(4711));
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(true));
|
||||
});
|
||||
}
|
||||
[Test]
|
||||
public void GetInteger_returnObjectDefault()
|
||||
{
|
||||
var key = GetInteger(_TestHive, _TestRootKey, "TestIntegerNotProvided");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo(-1), "Value should be the default (-1)");
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(false));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetInteger_returnSpecifiedDefault()
|
||||
{
|
||||
var key = GetInteger(_TestHive, _TestRootKey, "TestIntegerNotProvided", 2096);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo(-1), "Value should be the default (-1)");
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(false));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetDwordValue_returnIntegerValue()
|
||||
{
|
||||
int value = GetDwordValue(_TestHive, _TestRootKey, "TestInteger");
|
||||
Assert.That(value, Is.EqualTo(4711));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region GetString()
|
||||
[Test]
|
||||
public void GetString()
|
||||
{
|
||||
var key = GetString(_TestHive, _TestRootKey, "TestString1");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo("Banane"));
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(true));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetString_ReturnsDefault()
|
||||
{
|
||||
var key = GetString(_TestHive, _TestRootKey, "TestStringNotProvided", "Banane");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo("Banane"));
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(false));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetStringValidated_Valid()
|
||||
{
|
||||
string[] fruits = { "Banane", "Erdbeere", "Apfel" };
|
||||
var key = GetStringValidated(_TestHive, _TestRootKey, "TestString1", fruits);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo("Banane"));
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(key.IsValid, Is.EqualTo(true));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetStringValidated_NotValidNull()
|
||||
{
|
||||
string[] fruits = { "Banane", "Erdbeere", "Apfel" };
|
||||
var key = GetStringValidated(_TestHive, _TestRootKey, "TestString2", fruits);
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo(null));
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(key.IsValid, Is.EqualTo(false));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetStringValidated_NotValidDefault()
|
||||
{
|
||||
string[] fruits = { "Banane", "Erdbeere", "Apfel" };
|
||||
var key = GetStringValidated(_TestHive, _TestRootKey, "TestString2", fruits, false, "Banane");
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(key.Value, Is.EqualTo("Banane"));
|
||||
Assert.That(key.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(key.IsValid, Is.EqualTo(false));
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,386 +0,0 @@
|
||||
using Microsoft.Win32;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
using NUnit.Framework;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Rebar;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry
|
||||
{
|
||||
internal class WindowsRegistryKeyTests
|
||||
{
|
||||
private WindowsRegistryKey CompleteRegistryKey { get; set; }
|
||||
private WindowsRegistryKey PartialRegistryKey { get; set; }
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
CompleteRegistryKey = new WindowsRegistryKey()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.String,
|
||||
Name = "Test",
|
||||
Path = @"SOFTWARE\TEST\TEST\Test",
|
||||
Value = "CompleteRegistryKey"
|
||||
};
|
||||
|
||||
PartialRegistryKey = new WindowsRegistryKey()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
};
|
||||
}
|
||||
|
||||
#region WindowsRegistryKey() tests
|
||||
[Test]
|
||||
public void WindowsRegistryKeyReadable()
|
||||
{
|
||||
Assert.That(CompleteRegistryKey.IsKeyReadable, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyNotReadable()
|
||||
{
|
||||
Assert.That(PartialRegistryKey.IsKeyReadable, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyWriteable()
|
||||
{
|
||||
Assert.That(CompleteRegistryKey.IsKeyWritable, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyNotWriteable()
|
||||
{
|
||||
Assert.That(PartialRegistryKey.IsKeyWritable, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyProvided()
|
||||
{
|
||||
Assert.That(CompleteRegistryKey.IsKeyPresent, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyNotProvided()
|
||||
{
|
||||
Assert.That(PartialRegistryKey.IsKeyPresent, Is.EqualTo(false));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryKeyBoolean tests
|
||||
[Test]
|
||||
public void WindowsRegistryKeyBoolean_FromStringTrue()
|
||||
{
|
||||
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.String,
|
||||
Name = "TestBoolString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "true"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyBoolean boolKey = new ();
|
||||
boolKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(boolKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(boolKey.Value, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyBoolean_FromStringFalse()
|
||||
{
|
||||
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.String,
|
||||
Name = "TestBoolString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "false"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyBoolean boolKey = new();
|
||||
boolKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(boolKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(boolKey.Value, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyBoolean_FromDwordTrue()
|
||||
{
|
||||
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestBoolString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "1"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyBoolean boolKey = new();
|
||||
boolKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(boolKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(boolKey.Value, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyBoolean_FromDwordFalse()
|
||||
{
|
||||
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestBoolString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "0"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyBoolean boolKey = new();
|
||||
boolKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(boolKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(boolKey.Value, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyBoolean_ReturnDefault()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestBoolString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = null
|
||||
};
|
||||
|
||||
WindowsRegistryKeyBoolean boolKey = new();
|
||||
boolKey.ConvertFromWindowsRegistryKey(TestKey, true);
|
||||
|
||||
Assert.That(boolKey.IsKeyPresent, Is.EqualTo(false));
|
||||
Assert.That(boolKey.Value, Is.EqualTo(true));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryKeyInteger tests
|
||||
[Test]
|
||||
public void WindowsRegistryKeyInteger()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestIntigerString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "4711"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyInteger IntKey = new();
|
||||
IntKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(IntKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(IntKey.Value, Is.EqualTo(4711));
|
||||
}
|
||||
[Test]
|
||||
public void WindowsRegistryKeyInteger_ReturnDefault()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestIntigerString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = null
|
||||
};
|
||||
|
||||
WindowsRegistryKeyInteger IntKey = new();
|
||||
IntKey.ConvertFromWindowsRegistryKey(TestKey, 2096);
|
||||
|
||||
Assert.That(IntKey.IsKeyPresent, Is.EqualTo(false));
|
||||
Assert.That(IntKey.Value, Is.EqualTo(2096));
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistryKeyString tests
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "The Big Bang Theory"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new();
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(StrKey.Value, Is.EqualTo("The Big Bang Theory"));
|
||||
}
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString_ReturnDefault()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = null
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new();
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey, "South Park");
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(false));
|
||||
Assert.That(StrKey.Value, Is.EqualTo("South Park"));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString_ValidateSuccess()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "Big Bang"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new()
|
||||
{
|
||||
AllowedValues = new[] { "Big Bang", "Big Bang Theory", "The Big Bang Theory" }
|
||||
};
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(StrKey.IsValid, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString_ValidateNotSuccess()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "ig ang"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new()
|
||||
{
|
||||
AllowedValues = new[] { "Big Bang", "Big Bang Theory", "The Big Bang Theory" }
|
||||
};
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(StrKey.IsValid, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString_ValidateSuccessCase()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "BiG BAng"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new()
|
||||
{
|
||||
AllowedValues = new[] { "BiG BAng", "Big Bang Theory", "The Big Bang Theory" },
|
||||
IsCaseSensitiveValidation = true
|
||||
};
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(StrKey.IsValid, Is.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString_ValidateNotSuccessCase()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "BiG BAng"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new()
|
||||
{
|
||||
AllowedValues = new[] { "Big Bang", "Big Bang Theory", "The Big Bang Theory" },
|
||||
IsCaseSensitiveValidation = true
|
||||
};
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(StrKey.IsValid, Is.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString_ValidateNotSuccessReturnNull()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "ig ang"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new()
|
||||
{
|
||||
AllowedValues = new[] { "Big Bang", "Big Bang Theory", "The Big Bang Theory" }
|
||||
};
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey);
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(StrKey.IsValid, Is.EqualTo(false));
|
||||
Assert.That(StrKey.Value, Is.EqualTo(null));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyString_ValidateNotSuccessValidValue()
|
||||
{
|
||||
WindowsRegistryKey TestKey = new()
|
||||
{
|
||||
Hive = RegistryHive.CurrentUser,
|
||||
ValueKind = RegistryValueKind.DWord,
|
||||
Name = "TestRegString",
|
||||
Path = @"SOFTWARE\Test",
|
||||
Value = "ig ang"
|
||||
};
|
||||
|
||||
WindowsRegistryKeyString StrKey = new()
|
||||
{
|
||||
AllowedValues = new[] { "Big Bang", "Big Bang Theory", "The Big Bang Theory" }
|
||||
};
|
||||
StrKey.ConvertFromWindowsRegistryKey(TestKey, "Big Bang Theory");
|
||||
|
||||
Assert.That(StrKey.IsKeyPresent, Is.EqualTo(true));
|
||||
Assert.That(StrKey.IsValid, Is.EqualTo(false));
|
||||
Assert.That(StrKey.Value, Is.EqualTo("Big Bang Theory"));
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
@@ -1,195 +1,756 @@
|
||||
using System;
|
||||
using Microsoft.Win32;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Windows.Forms;
|
||||
using Microsoft.Win32;
|
||||
using System.Reflection;
|
||||
using mRemoteNG.Tools.WindowsRegistry;
|
||||
using NUnit.Framework;
|
||||
|
||||
namespace mRemoteNGTests.Tools.Registry
|
||||
{
|
||||
public class WindowsRegistryTests
|
||||
[SupportedOSPlatform("windows")]
|
||||
internal class WindowsRegistryTests : WinRegistry
|
||||
{
|
||||
private IRegistryRead _registryReader;
|
||||
private IRegistryWrite _registryWriter;
|
||||
private const string TestRoot = @"Software\mRemoteNGTest";
|
||||
private const RegistryHive TestHive = RegistryHive.CurrentUser;
|
||||
private const string TestPath = $"{TestRoot}\\WinRegistryTests";
|
||||
|
||||
[SetUp]
|
||||
public void Setup()
|
||||
{
|
||||
_registryReader = new WindowsRegistry();
|
||||
_registryWriter = new WindowsRegistry();
|
||||
}
|
||||
|
||||
#region GetSubKeyNames() tests
|
||||
[Test]
|
||||
public void CanGetSubkeyNames()
|
||||
#region WindowsRegistry.ThrowIfHiveInvalid()
|
||||
|
||||
private static MethodInfo? GetPrivateStaticMethod(string methodName)
|
||||
{
|
||||
var subKeyNames = _registryReader.GetSubKeyNames(RegistryHive.CurrentUser, "Software");
|
||||
Assert.That(subKeyNames, Does.Contain("Microsoft"));
|
||||
return typeof(WinRegistry).GetMethod(methodName, BindingFlags.NonPublic | BindingFlags.Static);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSubkeyNamesThrowsIfGivenNullKeyPath()
|
||||
public void ThrowIfHiveInvalid_ValidHive_DoesNotThrow()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _registryReader.GetSubKeyNames(RegistryHive.CurrentUser, null));
|
||||
var method = GetPrivateStaticMethod("ThrowIfHiveInvalid");
|
||||
if (method != null)
|
||||
Assert.DoesNotThrow(() => method.Invoke(null, new object[] { RegistryHive.LocalMachine }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfHiveInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetSubkeyNamesThrowsIfGivenUnknownHive()
|
||||
public void ThrowIfHiveInvalid_CurrentConfig_ThrowsArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => _registryReader.GetSubKeyNames(new RegistryHive(), "Software"));
|
||||
var method = GetPrivateStaticMethod("ThrowIfHiveInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { null }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfHiveInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowIfHiveInvalid_InvalidHive_ThrowsArgumentException()
|
||||
{
|
||||
var method = GetPrivateStaticMethod("ThrowIfHiveInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method ? .Invoke(null, new object[] { (RegistryHive)100 }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfHiveInvalid could not be found.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetPropertyValue() tests
|
||||
#region WindowsRegistry.ThrowIfPathInvalid()
|
||||
|
||||
[Test]
|
||||
public void CanGetPropertyValue()
|
||||
public void ThrowIfPathInvalid_ValidPath_DoesNotThrow()
|
||||
{
|
||||
var keyValue = _registryReader.GetPropertyValue(RegistryHive.ClassesRoot, @".dll\PersistentHandler", "");
|
||||
Assert.That(keyValue, Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
|
||||
var method = GetPrivateStaticMethod("ThrowIfPathInvalid");
|
||||
if (method != null)
|
||||
Assert.DoesNotThrow(() => method.Invoke(null, new object[] { @"SOFTWARE\Microsoft" }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfPathInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanGetPropertyValueByRegistryKeyObject()
|
||||
public void ThrowIfPathInvalid_NullPath_ThrowsArgumentException()
|
||||
{
|
||||
WindowsRegistryKey key = new()
|
||||
{
|
||||
Hive = RegistryHive.ClassesRoot,
|
||||
Path = @".dll\PersistentHandler",
|
||||
Name = ""
|
||||
};
|
||||
|
||||
var keyValue = _registryReader.GetPropertyValue(key);
|
||||
Assert.That(keyValue, Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
|
||||
}
|
||||
[Test]
|
||||
public void GetPropertyValueThrowsIfGivenNullKeyPath()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _registryReader.GetPropertyValue(RegistryHive.CurrentUser, null, ""));
|
||||
var method = GetPrivateStaticMethod("ThrowIfPathInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { null }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfPathInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetPropertyValueThrowsIfGivenNullPropertyName()
|
||||
public void ThrowIfPathInvalid_EmptyPath_ThrowsArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => _registryReader.GetPropertyValue(RegistryHive.CurrentUser, "", null));
|
||||
var method = GetPrivateStaticMethod("ThrowIfPathInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { string.Empty }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfPathInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowIfPathInvalid_WhitespacePath_ThrowsArgumentException()
|
||||
{
|
||||
var method = GetPrivateStaticMethod("ThrowIfPathInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { " " }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfPathInvalid could not be found.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetWindowsRegistryKey() tests
|
||||
#region WindowsRegistry.ThrowIfNameInvalid()
|
||||
|
||||
[Test]
|
||||
public void CanGetWindowsRegistryKey()
|
||||
public void ThrowIfNameInvalid_ValidName_DoesNotThrow()
|
||||
{
|
||||
WindowsRegistryKey keyValue = _registryReader.GetWindowsRegistryKey(RegistryHive.ClassesRoot, @".dll\PersistentHandler", "");
|
||||
Assert.That(keyValue.Value, Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
|
||||
var method = GetPrivateStaticMethod("ThrowIfNameInvalid");
|
||||
if (method != null)
|
||||
Assert.DoesNotThrow(() => method.Invoke(null, new object[] { "TestName" }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfNameInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanGetWindowsRegistryKeyByObject()
|
||||
public void ThrowIfNameInvalid_NullName_ThrowsArgumentNullException()
|
||||
{
|
||||
WindowsRegistryKey key = new()
|
||||
{
|
||||
Hive = RegistryHive.ClassesRoot,
|
||||
Path = @".dll\PersistentHandler",
|
||||
Name = ""
|
||||
};
|
||||
var method = GetPrivateStaticMethod("ThrowIfNameInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { null }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfNameInvalid could not be found.");
|
||||
}
|
||||
|
||||
WindowsRegistryKey keyValue = _registryReader.GetWindowsRegistryKey(key);
|
||||
Assert.That(keyValue.Value, Is.EqualTo("{098f2470-bae0-11cd-b579-08002b30bfeb}"));
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.ThrowIfValueKindInvalid()
|
||||
|
||||
[Test]
|
||||
public void ThrowIfValueKindInvalid_ValidValueKind_DoesNotThrow()
|
||||
{
|
||||
var method = GetPrivateStaticMethod("ThrowIfValueKindInvalid");
|
||||
if (method != null)
|
||||
Assert.DoesNotThrow(() => method.Invoke(null, new object[] { RegistryValueKind.String }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfValueKindInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanGetWindowsRegistryKeyForKeyNotExists()
|
||||
public void ThrowIfValueKindInvalid_InvalidValueKind_ThrowsArgumentException()
|
||||
{
|
||||
// No exception. Only null value
|
||||
WindowsRegistryKey keyValue = _registryReader.GetWindowsRegistryKey(RegistryHive.LocalMachine, @"Software\Testabcdefg", "abcdefg");
|
||||
Assert.That(keyValue.Value, Is.EqualTo(null));
|
||||
var method = GetPrivateStaticMethod("ThrowIfValueKindInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { (RegistryValueKind)100 }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfValueKindInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetWindowsRegistryThrowNotReadable()
|
||||
public void ThrowIfValueKindInvalid_ValueKindUnknown_ThrowsArgumentException()
|
||||
{
|
||||
WindowsRegistryKey key = new()
|
||||
{
|
||||
Hive = RegistryHive.ClassesRoot,
|
||||
};
|
||||
var method = GetPrivateStaticMethod("ThrowIfValueKindInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { RegistryValueKind.Unknown }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfValueKindInvalid could not be found.");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ThrowIfValueKindInvalid_ValueKindNone_ThrowsArgumentException()
|
||||
{
|
||||
var method = GetPrivateStaticMethod("ThrowIfValueKindInvalid");
|
||||
if (method != null)
|
||||
Assert.Throws<TargetInvocationException>(() => method.Invoke(null, new object[] { RegistryValueKind.None }));
|
||||
else
|
||||
Assert.Fail("The method ThrowIfValueKindInvalid could not be found.");
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.SetValue()
|
||||
|
||||
[Test]
|
||||
public void SetValue_NewKey_SetsValueSuccessfully()
|
||||
{
|
||||
const string testName = "TestValue";
|
||||
const string testValue = "Test1";
|
||||
const string testPath = TestPath + @"\SetValue";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
string key = GetStringValue(TestHive, testPath, testName, testValue);
|
||||
Assert.That(key, Is.EqualTo(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_OverwriteValue_SetsValueSuccessfully()
|
||||
{
|
||||
const string testName = "TestValue";
|
||||
const string testValue = "Test2";
|
||||
const string testPath = TestPath + @"\SetValue";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
string key = GetStringValue(TestHive, testPath, testName, testValue);
|
||||
Assert.That(key, Is.EqualTo(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetValue_DefaultValueWithWrongValueKind_SetsValueSuccessfully()
|
||||
{
|
||||
const string? testName = null;
|
||||
const string testValue = "SetDefault";
|
||||
const string testPath = TestPath + @"\SetValue";
|
||||
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.Unknown));
|
||||
|
||||
string key = GetStringValue(TestHive, testPath, testName, testValue);
|
||||
Assert.That(key, Is.EqualTo(testValue));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.CreateKey()
|
||||
|
||||
[Test]
|
||||
public void CreateKey_NewKey_CreatesKeySuccessfully()
|
||||
{
|
||||
const string testPath = TestPath + @"\TestSubKey";
|
||||
Assert.DoesNotThrow(() => CreateKey(TestHive, testPath));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateKey_ExistingKey_DoesNotThrow()
|
||||
{
|
||||
const string testPath = TestPath + @"\TestSubKey";
|
||||
Assert.DoesNotThrow(() => CreateKey(TestHive, testPath));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CreateKey_InvalidHive_ThrowsArgumentException()
|
||||
{
|
||||
Assert.Throws<ArgumentException>(() => CreateKey((RegistryHive)(-1), @"Software\Test"));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.GetSubKeyNames()
|
||||
|
||||
[Test]
|
||||
public void GetSubKeyNames_ExistingKey_ReturnsSubKeyNames()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetSubKeyNames";
|
||||
const string testSubKey1 = testPath + @"\subkey1";
|
||||
const string testSubKey2 = testPath + @"\subkey2";
|
||||
const string testSubKey3 = testPath + @"\subkey3";
|
||||
|
||||
CreateKey(TestHive, testSubKey1);
|
||||
CreateKey(TestHive, testSubKey2);
|
||||
CreateKey(TestHive, testSubKey3);
|
||||
|
||||
string[] subKeyNames = GetSubKeyNames(TestHive, testPath);
|
||||
|
||||
Assert.That(subKeyNames.Length, Is.EqualTo(3));
|
||||
Assert.That(subKeyNames, Contains.Item("subkey1"));
|
||||
Assert.That(subKeyNames, Contains.Item("subkey2"));
|
||||
Assert.That(subKeyNames, Contains.Item("subkey3"));
|
||||
}
|
||||
|
||||
Assert.Throws<InvalidOperationException>(() => _registryReader.GetWindowsRegistryKey(key));
|
||||
[Test]
|
||||
public void GetSubKeyNames_NonExistingKey_ReturnsEmptyArray()
|
||||
{
|
||||
string[] subKeyNames = GetSubKeyNames(TestHive, @"Software\NonExistingKey");
|
||||
Assert.That(subKeyNames, Is.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region GetRegistryEntries() + Recurse tests
|
||||
#region WindowsRegistry.GetValue()
|
||||
|
||||
[Test]
|
||||
public void CanGetRegistryEntries()
|
||||
public void GetValue_RetrieveValue_ReturnsValue()
|
||||
{
|
||||
List<WindowsRegistryKey> keys = _registryReader.GetRegistryEntries(RegistryHive.LocalMachine, @"HARDWARE\DESCRIPTION\System\BIOS");
|
||||
Assert.That(keys.Count, Is.Not.EqualTo(0));
|
||||
const string testPath = TestPath + @"\GetValue";
|
||||
const string testName = "TestValue";
|
||||
const string testValue = "Test";
|
||||
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
string key = GetValue(TestHive, testPath, testName);
|
||||
Assert.That(key, Is.EqualTo(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void CanGetRegistryEntriesRecurse()
|
||||
public void GetValue_RetrieveDefault_RetrunsValue()
|
||||
{
|
||||
List<WindowsRegistryKey> keys = _registryReader.GetRegistryEntryiesRecursive(RegistryHive.LocalMachine, @"SOFTWARE\Microsoft\Windows\Windows Search");
|
||||
Assert.That(keys.Count, Is.Not.EqualTo(0));
|
||||
const string testPath = TestPath + @"\GetValue";
|
||||
const string testName = "";
|
||||
const string testValue = "TestDefault{098f2470-bae0-11cd-b579-08002b30bfeb}";
|
||||
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
var key = GetValue(TestHive, testPath, testName);
|
||||
Assert.That(key, Is.EqualTo(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetValue_NonExistingValue_ReturnsNull()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetValue";
|
||||
const string nonExistingName = "NonExistingValue";
|
||||
|
||||
string key = GetValue(TestHive, testPath, nonExistingName);
|
||||
Assert.That(key, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void SetAndGetDefaultValue_RetrieveValue_ReturnsValue()
|
||||
{
|
||||
const string testPath = TestPath + @"\DefautValue";
|
||||
const string testValue = "DefaultTestTestValue";
|
||||
|
||||
Assert.DoesNotThrow(() => SetDefaultValue(TestHive, testPath, testValue));
|
||||
|
||||
string key = GetDefaultValue(TestHive, testPath);
|
||||
Assert.That(key, Is.EqualTo(testValue));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region new WindowsRegistryKey() tests
|
||||
#region WindowsRegistry.GetStringValue()
|
||||
|
||||
[Test]
|
||||
public void IsWindowsRegistryKeyValid()
|
||||
public void GetStringValue_RetrieveValue_ReturnsValue()
|
||||
{
|
||||
// Tests property rules of WindowsRegistryKey
|
||||
WindowsRegistryKey key = new();
|
||||
const string testPath = TestPath + @"\GetStringValue";
|
||||
const string testName = "TestValue";
|
||||
const string testValue = "Test";
|
||||
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
var key = GetStringValue(TestHive, testPath, testName);
|
||||
Assert.That(key, Is.TypeOf<string>().And.EqualTo(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetStringValue_RetrieveDefault_ReturnsValue()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetStringValue";
|
||||
const string testName = "";
|
||||
const string testValue = "TestDefault{098f2470-bae0-11cd-b579-08002b30bfeb}";
|
||||
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
var key = GetStringValue(TestHive, testPath, testName);
|
||||
Assert.That(key, Is.TypeOf<string>().And.EqualTo(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetStringValue_NonExistingValue_ReturnsNull()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetStringValue";
|
||||
const string nonExistingName = "NonExistingValue";
|
||||
|
||||
var key = GetStringValue(TestHive, testPath, nonExistingName);
|
||||
Assert.That(key, Is.Null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetStringValue_NonExistingValue_ReturnsDefault()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetStringValue";
|
||||
const string nonExistingName = "NonExistingValue";
|
||||
const string defaultValue = "DefaultValue";
|
||||
|
||||
string key = GetStringValue(TestHive, testPath, nonExistingName, defaultValue);
|
||||
Assert.That(key, Is.TypeOf<string>().And.EqualTo(defaultValue));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.GetBoolValue()
|
||||
|
||||
[Test]
|
||||
public void GetBoolValue_FromString_ReturnsTrue()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetBoolValue";
|
||||
const string testName = "strBool_true";
|
||||
const string testValue = "true";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
var key = GetBoolValue(TestHive, testPath, testName, false); // set default to false
|
||||
Assert.That(key, Is.TypeOf<bool>().And.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBoolValue_FromString_ReturnsFalse()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetBoolValue";
|
||||
const string testName = "strBool_false";
|
||||
const string testValue = "false";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
|
||||
var key = GetBoolValue(TestHive, testPath, testName, true); // set default to true
|
||||
Assert.That(key, Is.TypeOf<bool>().And.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBoolValue_FromDword_ReturnsFalse()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetBoolValue";
|
||||
const string testName = "intBool_false";
|
||||
const int testValue = 0;
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.DWord));
|
||||
|
||||
var key = GetBoolValue(TestHive, testPath, testName, true); // set default to true
|
||||
Assert.That(key, Is.TypeOf<bool>().And.EqualTo(false));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBoolValue_FromDword_ReturnsTrue()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetBoolValue";
|
||||
const string testName = "intBool_true";
|
||||
const int testValue = 1;
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.DWord));
|
||||
|
||||
var key = GetBoolValue(TestHive, testPath, testName, false); // set default to false
|
||||
Assert.That(key, Is.TypeOf<bool>().And.EqualTo(true));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetBoolValue_NonExistingValue_ReturnsFalse()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetStringValue";
|
||||
const string nonExistingName = "NonExistingValue";
|
||||
|
||||
var key = GetBoolValue(TestHive, testPath, nonExistingName);
|
||||
Assert.That(key, Is.TypeOf<bool>().And.EqualTo(false));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.GetDwordValue()
|
||||
|
||||
[Test]
|
||||
public void GetIntegerValue_RetrieveValue_ReturnsValue()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetIntegerValue";
|
||||
const string testName = "ExistingDword";
|
||||
const int testValue = 2;
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.DWord));
|
||||
|
||||
var key = GetIntegerValue(TestHive, testPath, testName);
|
||||
Assert.That(key, Is.TypeOf<int>().And.EqualTo(testValue));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIntegerValue_NonExistingValue_ReturnsZero()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetStringValue";
|
||||
const string nonExistingName = "NonExistingValue";
|
||||
|
||||
var key = GetIntegerValue(TestHive, testPath, nonExistingName);
|
||||
Assert.That(key, Is.TypeOf<int>().And.EqualTo(0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void GetIntegerValue_NotExistingKey_ReturnsDefault()
|
||||
{
|
||||
const string testPath = TestPath + @"\GetStringValue";
|
||||
const string testName = "NotExistingDword";
|
||||
|
||||
var key = GetIntegerValue(TestHive, testPath, testName, 12); // set default to true
|
||||
Assert.That(key, Is.TypeOf<int>().And.EqualTo(12));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.GetEntry()
|
||||
|
||||
[Test]
|
||||
public void GetRegistryEntry_ReturnsCorrectEntry()
|
||||
{
|
||||
const string testName = "TestValue";
|
||||
const int testValue = 2011;
|
||||
const string testPath = TestPath + @"\GetRegistryEntry";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.DWord));
|
||||
|
||||
var entry = GetEntry(TestHive, testPath, testName);
|
||||
|
||||
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", "");
|
||||
Assert.That(entry.Hive, Is.EqualTo(TestHive));
|
||||
Assert.That(entry.Path, Is.EqualTo(testPath));
|
||||
Assert.That(entry.Name, Is.EqualTo(testName));
|
||||
Assert.That(entry.ValueKind, Is.EqualTo(RegistryValueKind.DWord));
|
||||
Assert.That(entry.IsSet, Is.EqualTo(true));
|
||||
});
|
||||
|
||||
}
|
||||
[Test]
|
||||
public void WindowsRegistryKeyThrowHiveNullException()
|
||||
{
|
||||
WindowsRegistryKey key = new();
|
||||
Assert.Throws<ArgumentNullException>(() => key.Hive = 0, "Expected IsHiveValid to throw ArgumentNullException");
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyValueKindUnknown()
|
||||
{
|
||||
WindowsRegistryKey key = new();
|
||||
Assert.That(key.ValueKind, Is.EqualTo(RegistryValueKind.Unknown));
|
||||
#endregion
|
||||
|
||||
#region WinRegistryEC.GetRegistryEntries()
|
||||
|
||||
}
|
||||
[Test]
|
||||
public void WindowsRegistryKeyThrowPathNullException()
|
||||
public void GetRegistryEntries_ReturnsCorrectEntries()
|
||||
{
|
||||
WindowsRegistryKey key = new();
|
||||
Assert.Throws<ArgumentNullException>(() => key.Path = null, "Expected IsPathValid to throw ArgumentNullException");
|
||||
const string testPath = TestPath + @"\GetRegistryEntries";
|
||||
const string testNamePrefix = "TestEntry";
|
||||
const string testValue = "winRegEntriesTest";
|
||||
|
||||
for (int i = 1; i <= 10; i++)
|
||||
{
|
||||
string testName = $"{testNamePrefix}{i}";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
}
|
||||
|
||||
const string testPathSubkeys = testPath + @"\Subkey";
|
||||
const string testNameSubKey = "TestSubEntry";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPathSubkeys, testNameSubKey, testValue, RegistryValueKind.String));
|
||||
|
||||
var entries = GetEntries(TestHive, testPath);
|
||||
|
||||
|
||||
Assert.That(entries, Is.Not.Null);
|
||||
Assert.That(entries, Is.Not.Empty);
|
||||
Assert.That(entries, Is.InstanceOf<List<WinRegistryEntry<string>>>());
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entry.Name, Is.Not.Null & Is.Not.EqualTo(testNameSubKey)); //Subkeys should not be read (non-recursive).
|
||||
|
||||
Assert.That(entry.Hive, Is.EqualTo(TestHive));
|
||||
Assert.That(entry.Path, Is.EqualTo(testPath));
|
||||
Assert.That(entry.Value, Is.EqualTo(testValue));
|
||||
Assert.That(entry.ValueKind, Is.EqualTo(RegistryValueKind.String));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WinRegistryEC.GetRegistryEntriesRecursive()
|
||||
|
||||
[Test]
|
||||
public void WindowsRegistryKeyThrowNameNullException()
|
||||
public void GetRegistryEntriesRecursive_ReturnsCorrectEntries()
|
||||
{
|
||||
WindowsRegistryKey key = new();
|
||||
Assert.Throws<ArgumentNullException>(() => key.Name = null, "Expected IsNameValid to throw ArgumentNullException");
|
||||
const string testPath = TestPath + @"\GetRegistryEntriesRecursive";
|
||||
const string testNamePrefix = "TestEntry";
|
||||
const string testValue = "winRegEntriesTest";
|
||||
|
||||
for (int i = 1; i <= 10; i++)
|
||||
{
|
||||
string testName = $"{testNamePrefix}{i}";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName, testValue, RegistryValueKind.String));
|
||||
}
|
||||
|
||||
const string testSubkeyPath = testPath + @"\Subkey";
|
||||
const string testNameSubKey = "TestSubEntry";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testSubkeyPath, testNameSubKey, testValue, RegistryValueKind.String));
|
||||
|
||||
var entries = GetEntriesRecursive(TestHive, testPath);
|
||||
|
||||
Assert.That(entries, Is.Not.Null);
|
||||
Assert.That(entries, Is.Not.Empty);
|
||||
Assert.That(entries, Is.InstanceOf<List< WinRegistryEntry<string>>> ());
|
||||
|
||||
// Assert that the subkey is included in the entries list
|
||||
Assert.That(entries.Any(e => e.Name == testNameSubKey), Is.True, "Subkey entry should be included in the entries list.");
|
||||
|
||||
foreach (var entry in entries)
|
||||
{
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(entry.Name, Is.Not.Null);
|
||||
Assert.That(entry.Hive, Is.EqualTo(TestHive));
|
||||
Assert.That(entry.Value, Is.EqualTo(testValue));
|
||||
Assert.That(entry.ValueKind, Is.EqualTo(RegistryValueKind.String));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.DeleteRegistryValue()
|
||||
[Test]
|
||||
public void DeleteRegistryValue_DeletesValue()
|
||||
{
|
||||
const string testPath = TestPath + @"\DeleteRegistryValue";
|
||||
const string testName01 = "TestValue01";
|
||||
const string testName02 = "TestValue02";
|
||||
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName01, "Test", RegistryValueKind.String));
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, testPath, testName02, "Test", RegistryValueKind.String));
|
||||
|
||||
Assert.DoesNotThrow(() => DeleteRegistryValue(TestHive, testPath, testName01));
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(GetStringValue(TestHive, testPath, testName01), Is.Null);
|
||||
Assert.That(GetStringValue(TestHive, testPath, testName02), Is.Not.Null);
|
||||
});
|
||||
}
|
||||
#endregion
|
||||
|
||||
#region SetRegistryValue() tests
|
||||
[Test]
|
||||
public void CanSetRegistryValue()
|
||||
{
|
||||
Assert.DoesNotThrow(() => _registryWriter.SetRegistryValue(RegistryHive.CurrentUser, @"SOFTWARE\mRemoteNGTest", "TestKey", "A value string", RegistryValueKind.String));
|
||||
}
|
||||
#region WindowsRegistry.DeleteTree()
|
||||
|
||||
[Test]
|
||||
public void SetRegistryValueThrowAccessDenied()
|
||||
public void DeleteTree_RemovesKeyAndSubkeys()
|
||||
{
|
||||
Assert.Throws<InvalidOperationException>(() => _registryWriter.SetRegistryValue(RegistryHive.LocalMachine, @"SOFTWARE\mRemoteNGTest", "TestKey", "A value string", RegistryValueKind.String));
|
||||
const string testPath = TestPath + @"\DeleteTree";
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, $"{testPath}\\Subkey0", "Test", "Test", RegistryValueKind.String));
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, $"{testPath}\\Subkey1", "Test", "Test", RegistryValueKind.String));
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, $"{testPath}\\Subkey2", "Test", "Test", RegistryValueKind.String));
|
||||
Assert.DoesNotThrow(() => SetValue(TestHive, $"{testPath}\\Subkey3", "Test", "Test", RegistryValueKind.String));
|
||||
|
||||
Assert.DoesNotThrow(() => DeleteTree(TestHive, testPath));
|
||||
Assert.That(GetSubKeyNames(TestHive, testPath), Is.Empty);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.ConvertStringToRegistryHive()
|
||||
|
||||
[Test]
|
||||
public void ConvertStringToRegistryHive_ReturnsCorrectValue()
|
||||
{
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ConvertStringToRegistryHive("HKCR"), Is.EqualTo(RegistryHive.ClassesRoot));
|
||||
Assert.That(ConvertStringToRegistryHive("HKey_Classes_Root"), Is.EqualTo(RegistryHive.ClassesRoot));
|
||||
Assert.That(ConvertStringToRegistryHive("ClassesRoot"), Is.EqualTo(RegistryHive.ClassesRoot));
|
||||
|
||||
Assert.That(ConvertStringToRegistryHive("HKCU"), Is.EqualTo(RegistryHive.CurrentUser));
|
||||
Assert.That(ConvertStringToRegistryHive("HKey_Current_User"), Is.EqualTo(RegistryHive.CurrentUser));
|
||||
Assert.That(ConvertStringToRegistryHive("currentuser"), Is.EqualTo(RegistryHive.CurrentUser));
|
||||
|
||||
Assert.That(ConvertStringToRegistryHive("HKLM"), Is.EqualTo(RegistryHive.LocalMachine));
|
||||
Assert.That(ConvertStringToRegistryHive("HKey_Local_Machine"), Is.EqualTo(RegistryHive.LocalMachine));
|
||||
Assert.That(ConvertStringToRegistryHive("LocalMachine"), Is.EqualTo(RegistryHive.LocalMachine));
|
||||
|
||||
Assert.That(ConvertStringToRegistryHive("HKU"), Is.EqualTo(RegistryHive.Users));
|
||||
Assert.That(ConvertStringToRegistryHive("HKey_users"), Is.EqualTo(RegistryHive.Users));
|
||||
Assert.That(ConvertStringToRegistryHive("Users"), Is.EqualTo(RegistryHive.Users));
|
||||
|
||||
Assert.That(ConvertStringToRegistryHive("HKCC"), Is.EqualTo(RegistryHive.CurrentConfig));
|
||||
Assert.That(ConvertStringToRegistryHive("HKey_Current_Config"), Is.EqualTo(RegistryHive.CurrentConfig));
|
||||
Assert.That(ConvertStringToRegistryHive("CurrentConfig"), Is.EqualTo(RegistryHive.CurrentConfig));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertStringToRegistryHive_InvalidHiveNull_ThrowArgumentNullException()
|
||||
{
|
||||
Assert.That(() => ConvertStringToRegistryHive(null), Throws.ArgumentNullException);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertStringToRegistryHive_InvalidHive_ThrowArgumentException()
|
||||
{
|
||||
Assert.That(() => ConvertStringToRegistryHive("InvalidHive"), Throws.ArgumentException);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.ConvertStringToRegistryValueKind()
|
||||
|
||||
[Test]
|
||||
public void ConvertStringToRegistryValueKind_ReturnsCorrectValue()
|
||||
{
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ConvertStringToRegistryValueKind("string"), Is.EqualTo(RegistryValueKind.String));
|
||||
Assert.That(ConvertStringToRegistryValueKind("reg_sz"), Is.EqualTo(RegistryValueKind.String));
|
||||
|
||||
Assert.That(ConvertStringToRegistryValueKind("dword"), Is.EqualTo(RegistryValueKind.DWord));
|
||||
Assert.That(ConvertStringToRegistryValueKind("reg_dword"), Is.EqualTo(RegistryValueKind.DWord));
|
||||
|
||||
Assert.That(ConvertStringToRegistryValueKind("binary"), Is.EqualTo(RegistryValueKind.Binary));
|
||||
Assert.That(ConvertStringToRegistryValueKind("reg_binary"), Is.EqualTo(RegistryValueKind.Binary));
|
||||
|
||||
Assert.That(ConvertStringToRegistryValueKind("qword"), Is.EqualTo(RegistryValueKind.QWord));
|
||||
Assert.That(ConvertStringToRegistryValueKind("reg_qword"), Is.EqualTo(RegistryValueKind.QWord));
|
||||
|
||||
Assert.That(ConvertStringToRegistryValueKind("multistring"), Is.EqualTo(RegistryValueKind.MultiString));
|
||||
Assert.That(ConvertStringToRegistryValueKind("reg_multi_sz"), Is.EqualTo(RegistryValueKind.MultiString));
|
||||
|
||||
Assert.That(ConvertStringToRegistryValueKind("expandstring"), Is.EqualTo(RegistryValueKind.ExpandString));
|
||||
Assert.That(ConvertStringToRegistryValueKind("reg_expand_sz"), Is.EqualTo(RegistryValueKind.ExpandString));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertStringToRegistryValueKind_InvalidHiveNull_ThrowArgumentNullException()
|
||||
{
|
||||
Assert.That(() => ConvertStringToRegistryValueKind(null), Throws.ArgumentNullException);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertStringToRegistryValueKind_InvalidHive_ThrowArgumentException()
|
||||
{
|
||||
Assert.That(() => ConvertStringToRegistryValueKind("InvalidKind"), Throws.ArgumentException);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.ConvertTypeToRegistryValueKind()
|
||||
|
||||
[Test]
|
||||
public void ConvertTypeToRegistryValueKind_ReturnsCorrectValue()
|
||||
{
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ConvertTypeToRegistryValueKind(typeof(string)), Is.EqualTo(RegistryValueKind.String));
|
||||
Assert.That(ConvertTypeToRegistryValueKind(typeof(int)), Is.EqualTo(RegistryValueKind.DWord));
|
||||
Assert.That(ConvertTypeToRegistryValueKind(typeof(long)), Is.EqualTo(RegistryValueKind.QWord));
|
||||
Assert.That(ConvertTypeToRegistryValueKind(typeof(bool)), Is.EqualTo(RegistryValueKind.DWord));
|
||||
Assert.That(ConvertTypeToRegistryValueKind(typeof(byte)), Is.EqualTo(RegistryValueKind.Binary));
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertTypeToRegistryValueKind_UnknownType_ReturnsString()
|
||||
{
|
||||
Assert.That(ConvertTypeToRegistryValueKind(typeof(Single)), Is.EqualTo(RegistryValueKind.String));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void ConvertTypeToRegistryValueKind_WithNullValueType_ThrowsArgumentNullException()
|
||||
{
|
||||
Assert.Throws<ArgumentNullException>(() => ConvertTypeToRegistryValueKind(null));
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region WindowsRegistry.ConvertRegistryValueKindToType()
|
||||
|
||||
[Test]
|
||||
public void ConvertRegistryValueKindToType_ReturnsCorrectType()
|
||||
{
|
||||
Assert.Multiple(() =>
|
||||
{
|
||||
Assert.That(ConvertRegistryValueKindToType(RegistryValueKind.String), Is.EqualTo(typeof(string)));
|
||||
Assert.That(ConvertRegistryValueKindToType(RegistryValueKind.ExpandString), Is.EqualTo(typeof(string)));
|
||||
Assert.That(ConvertRegistryValueKindToType(RegistryValueKind.DWord), Is.EqualTo(typeof(int)));
|
||||
Assert.That(ConvertRegistryValueKindToType(RegistryValueKind.QWord), Is.EqualTo(typeof(long)));
|
||||
Assert.That(ConvertRegistryValueKindToType(RegistryValueKind.Binary), Is.EqualTo(typeof(byte[])));
|
||||
Assert.That(ConvertRegistryValueKindToType(RegistryValueKind.MultiString), Is.EqualTo(typeof(string[])));
|
||||
Assert.That(ConvertRegistryValueKindToType((RegistryValueKind)100), Is.EqualTo(typeof(object)));
|
||||
});
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
[OneTimeTearDown]
|
||||
public void Cleanup()
|
||||
{
|
||||
// Delete all created tests
|
||||
DeleteTree(TestHive, TestPath);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user