Vanara/Windows.Shell.Common/Registration/RegBasedSettings.cs

105 lines
4.4 KiB
C#

using Microsoft.Win32;
using System;
namespace Vanara.Windows.Shell
{
/// <summary>Base class for registry based settings.</summary>
public abstract class RegBasedSettings : IDisposable, IEquatable<RegBasedSettings>, IComparable<RegBasedSettings>
{
/// <summary>The base key from which to perform all queries.</summary>
protected internal RegistryKey key;
/// <summary>Initializes a new instance of the <see cref="RegBasedSettings"/> class.</summary>
/// <param name="key">The key to use as the base key for queries.</param>
/// <param name="readOnly">if set to <c>true</c> the supplied <paramref name="key"/> was opened read-only.</param>
protected RegBasedSettings(RegistryKey key, bool readOnly)
{
this.key = key ?? throw new ArgumentNullException(nameof(key));
ReadOnly = readOnly;
}
/// <summary>Gets a value indicating whether this instance is system wide.</summary>
/// <value><see langword="true"/> if this instance is system wide; otherwise, <see langword="false"/>.</value>
public bool IsSystemWide => !key.Name.StartsWith("HKEY_CURRENT_USER");
/// <summary>Gets or sets a value indicating whether these settings are read-only.</summary>
public bool ReadOnly { get; }
/// <inheritdoc/>
public bool Equals(RegBasedSettings other) => ((IComparable<RegBasedSettings>)this).CompareTo(other) == 0;
/// <inheritdoc/>
public override int GetHashCode() => key?.Name.GetHashCode() ?? 0;
/// <inheritdoc/>
public override string ToString() => key?.ToString() ?? "";
/// <inheritdoc/>
int IComparable<RegBasedSettings>.CompareTo(RegBasedSettings other) => string.Compare(key.Name, other?.key.Name, StringComparison.InvariantCulture);
/// <inheritdoc/>
public virtual void Dispose()
{
key?.Close();
ShellRegistrar.NotifyShell();
}
/// <summary>Checks the ReadOnly flag and throws an exception if it is true.</summary>
protected void EnsureWritable() { if (ReadOnly) throw new InvalidOperationException("Object is read only and its values cannot be changed."); }
/// <summary>Toggles the value identified by having a named subkey present.</summary>
/// <param name="name">The name of the subkey.</param>
/// <param name="set">if set to <c>true</c>, creates a subkey named <paramref name="name"/>; otherwise deletes that subkey.</param>
protected void ToggleKeyValue(string name, bool set)
{
EnsureWritable();
if (!set)
key.DeleteSubKey(name, false);
else
key.CreateSubKey(name)?.Close();
}
/// <summary>Toggles the value identified by having a named value present.</summary>
/// <param name="name">The name of the value.</param>
/// <param name="set">if set to <c>true</c>, creates a value named <paramref name="name"/>; otherwise deletes that value.</param>
protected void ToggleValue(string name, bool set)
{
EnsureWritable();
if (!set)
key.DeleteValue(name, false);
else
key.SetValue(name, "", RegistryValueKind.String);
}
/// <summary>Updates the value identified by having a named subkey with its default value set.</summary>
/// <param name="name">The name of the subkey.</param>
/// <param name="value">The value of the default value.</param>
/// <param name="deleteIfValue">The value that, if equal to <paramref name="value"/>, causes the removal of the subkey.</param>
protected internal void UpdateKeyValue(string name, string value, string deleteIfValue = null)
{
EnsureWritable();
if (Equals(value, deleteIfValue))
key.DeleteSubKey(name, false);
else
key.CreateSubKey(name, value).Close();
}
/// <summary>Updates the value identified by having a named value.</summary>
/// <typeparam name="T">Type of the value</typeparam>
/// <param name="name">The name of the value.</param>
/// <param name="value">The value of the value.</param>
/// <param name="valueKind">Kind of the value.</param>
/// <param name="deleteIfValue">The value that, if equal to <paramref name="value"/>, causes the removal of the value.</param>
protected internal void UpdateValue<T>(string name, T value, RegistryValueKind valueKind = RegistryValueKind.Unknown, T deleteIfValue = default)
{
EnsureWritable();
if (Equals(value, deleteIfValue))
key.DeleteValue(name, false);
else
{
var o = value is Guid g ? (object)g.ToRegString() : value;
key.SetValue(name, value, valueKind == RegistryValueKind.Unknown && o is string ? RegistryValueKind.ExpandString : valueKind);
}
}
}
}