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));
+        }
+    }
+}