using System.Collections.Generic; using System.ComponentModel; using System.Diagnostics.CodeAnalysis; using System.Linq; namespace Vanara.Windows.Shell; /// A dictionary of Command Verbs defined in the Windows Registry. /// public class CommandVerbDictionary : RegBasedDictionary { private const string rootKeyName = "shell"; private readonly RegBasedSettings parent; internal CommandVerbDictionary(RegBasedSettings parent, bool readOnly) : base(parent.key?.OpenSubKey(rootKeyName, !readOnly), readOnly) => this.parent = parent; /// Gets or sets the default verb. /// The default verb. [DefaultValue(null)] public string? DefaultVerb { get => key?.GetValue(null)?.ToString(); set { if (ContainsKey(value)) key?.SetValue(null, value!); else throw new KeyNotFoundException("The command verb specified is not defined."); } } /// Get the filtered list of keys under the base. [Browsable(false)] public override IEnumerable Keys => key?.GetSubKeyNames() ?? new string[0]; /// Gets or sets the order of the command verbs. /// The ordered list of command verbs. [Browsable(false)] public IList Order { get { var order = key?.GetValue("", null)?.ToString(); var vals = Values.ToList(); if (order != null) { var orderedItems = order.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); for (var i = orderedItems.Length - 1; i >= 0; i--) { var match = vals.Find(c => string.Equals(c.Name, orderedItems[i], StringComparison.InvariantCultureIgnoreCase)); if (match == null) continue; vals.Remove(match); vals.Insert(0, match); } } return vals; } set { switch (value?.Count ?? 0) { case 0: key?.DeleteValue("", false); break; case 1: key?.SetValue("", value!.First().Name); break; default: key?.SetValue("", string.Join(",", value!.Select(c => c.Name).ToArray())); break; } } } /// Adds the specified command verb. /// The command verb name. /// /// The command verb display name. This is the string shown to the user when requesting a context menu for a shell item. /// /// The command to execute. /// if set to set this verb as default. /// A instance which has been added to the registry. public CommandVerb Add(string verb, string? displayName = null, string? command = null, bool setAsDefault = false) { if (key == null && !readOnly) key = parent.key?.CreateSubKey(rootKeyName); var vkey = key?.CreateSubKey(verb) ?? throw new InvalidOperationException("Unable to create required key in registry."); var v = new CommandVerb(vkey, verb, false) { DisplayName = displayName, Command = command }; if (setAsDefault) key?.SetValue(null, verb); return v; } /// Determines if a specified key is in the filtered list of keys under the base. /// The name of the key to check. /// if the key is found; otherwise . public override bool ContainsKey(string? verb) => verb is null ? false : key?.HasSubKey(verb) ?? false; /// Removes the specified key from this dictionary and the registry. /// The name of the command verb to remove. /// A value indicating success () or failure (). public bool Remove(string verb) { try { key?.DeleteSubKeyTree(verb); return true; } catch { return false; } } /// Tries to get the with the name . /// The verb name. /// On success, the corresponding instance; on failure. /// A value indicating if was found. public override bool TryGetValue(string verb, [NotNullWhen(true)] out CommandVerb? value) { value = null; if (!ContainsKey(verb)) return false; value = new CommandVerb(key?.OpenSubKey(verb, !readOnly)!, verb, readOnly); return true; } }