Mercurial > shortcutkeyfinder
diff ShortcutKeyFinder/ShortcutKeyFinder.cs @ 0:209d9210c18f default tip
It works.
author | Brad Greco <brad@bgreco.net> |
---|---|
date | Sat, 25 Jun 2016 13:42:54 +1000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/ShortcutKeyFinder/ShortcutKeyFinder.cs Sat Jun 25 13:42:54 2016 +1000 @@ -0,0 +1,96 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.IO; +using System.Linq; + +namespace ShortcutKeyFinder +{ + /// <summary>Class to find all shortcuts that have hotkeys assigned</summary> + /// <remarks>As far as I can tell, Windows only looks for shortcut hotkeys in the Start Menu and on the Desktop. So this class does as well.</remarks> + class ShortcutKeyFinder + { + private bool _showAll; + private List<Shortcut> _allShortcuts = new List<Shortcut>(); // List to hold all the shortcuts we find, regardless of whether they have hotkeys + + /// <summary>List of all shortcuts found in the search locations</summary> + /// <remarks>If <see cref="ShowAll"/> is true, shortcuts without assigned hotkeys are included</remarks> + public BindingList<Shortcut> Shortcuts { get; private set; } + + /// <summary>Indicates whether to include shortcuts without assigned hotkeys in the list of <see cref="Shortcuts"/></summary> + public bool ShowAll + { + get { return _showAll; } + set + { + _showAll = value; + UpdateShortcutList(); + } + } + + /// <summary>Constructor</summary> + public ShortcutKeyFinder() + { + Shortcuts = new BindingList<Shortcut>(); + } + + /// <summary>Scans the search locations for shortcut files</summary> + /// <param name="Admin">Whether to consider shortcuts owned by all users as read-only</param> + public void LoadShortcuts(bool Admin = false) + { + // Reset the master list and rescan the search directories + _allShortcuts.Clear(); + LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), false); + LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu), !Admin); + LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), false); + LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory), !Admin); + // Update the public list with what we found + UpdateShortcutList(); + } + + /// <summary>Recursively scans a directory shortcut files</summary> + /// <param name="path">Directory to scan</param> + /// <param name="readOnly">Whether to consider the found shortcuts as read-only</param> + /// <remarks>The <paramref name="readOnly"/> parameter exists for speed, to avoid checking permissions on every file. Good enough for our purposes.</remarks> + private void LoadShortcuts(string path, bool readOnly) + { + try + { + foreach (string lnk in Directory.EnumerateFiles(path, "*.lnk", SearchOption.AllDirectories)) + _allShortcuts.Add(new Shortcut(lnk) { ReadOnly = readOnly }); + } + catch { } // Silently ignore access denied errors, likely nothing the user can do about it anyway + } + + /// <summary>Updates the public list of <see cref="Shortcuts"/> with the results of the most recent scan</summary> + private void UpdateShortcutList() + { + // Remove event handlers while we're manipulating the list + Shortcuts.ListChanged -= Shortcuts_ListChanged; + + // Reset the list and add all appropriate shortcuts based on the current value of ShowAll + Shortcuts.Clear(); + foreach (Shortcut shortcut in _allShortcuts) + if (shortcut.Hotkey != null || _showAll) + Shortcuts.Add(shortcut); + + // Go through the list and look for duplicates + FindDuplicateShortcuts(); + + // Re-add event handlers + Shortcuts.ListChanged += Shortcuts_ListChanged; + } + + /// <summary>Triggers a search for duplicate shortcuts when one of the shortcuts changes</summary> + void Shortcuts_ListChanged(object sender, ListChangedEventArgs e) + { + FindDuplicateShortcuts(); + } + + /// <summary>Scans for shortcuts that have duplicate hotkeys</summary> + private void FindDuplicateShortcuts() + { + Shortcuts.GroupBy(shortcut => shortcut.Hotkey).ToList().ForEach(group => group.ToList().ForEach(shortcut => shortcut.HasDuplicateHotkey = group.Count() > 1 && group.Key != null)); + } + } +}