annotate 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
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
1 using System;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
2 using System.Collections.Generic;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
3 using System.ComponentModel;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
4 using System.IO;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
5 using System.Linq;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
6
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
7 namespace ShortcutKeyFinder
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
8 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
9 /// <summary>Class to find all shortcuts that have hotkeys assigned</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
10 /// <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>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
11 class ShortcutKeyFinder
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
12 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
13 private bool _showAll;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
14 private List<Shortcut> _allShortcuts = new List<Shortcut>(); // List to hold all the shortcuts we find, regardless of whether they have hotkeys
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
15
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
16 /// <summary>List of all shortcuts found in the search locations</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
17 /// <remarks>If <see cref="ShowAll"/> is true, shortcuts without assigned hotkeys are included</remarks>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
18 public BindingList<Shortcut> Shortcuts { get; private set; }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
19
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
20 /// <summary>Indicates whether to include shortcuts without assigned hotkeys in the list of <see cref="Shortcuts"/></summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
21 public bool ShowAll
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
22 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
23 get { return _showAll; }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
24 set
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
25 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
26 _showAll = value;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
27 UpdateShortcutList();
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
28 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
29 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
30
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
31 /// <summary>Constructor</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
32 public ShortcutKeyFinder()
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
33 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
34 Shortcuts = new BindingList<Shortcut>();
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
35 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
36
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
37 /// <summary>Scans the search locations for shortcut files</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
38 /// <param name="Admin">Whether to consider shortcuts owned by all users as read-only</param>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
39 public void LoadShortcuts(bool Admin = false)
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
40 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
41 // Reset the master list and rescan the search directories
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
42 _allShortcuts.Clear();
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
43 LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.StartMenu), false);
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
44 LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.CommonStartMenu), !Admin);
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
45 LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.DesktopDirectory), false);
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
46 LoadShortcuts(Environment.GetFolderPath(Environment.SpecialFolder.CommonDesktopDirectory), !Admin);
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
47 // Update the public list with what we found
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
48 UpdateShortcutList();
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
49 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
50
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
51 /// <summary>Recursively scans a directory shortcut files</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
52 /// <param name="path">Directory to scan</param>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
53 /// <param name="readOnly">Whether to consider the found shortcuts as read-only</param>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
54 /// <remarks>The <paramref name="readOnly"/> parameter exists for speed, to avoid checking permissions on every file. Good enough for our purposes.</remarks>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
55 private void LoadShortcuts(string path, bool readOnly)
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
56 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
57 try
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
58 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
59 foreach (string lnk in Directory.EnumerateFiles(path, "*.lnk", SearchOption.AllDirectories))
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
60 _allShortcuts.Add(new Shortcut(lnk) { ReadOnly = readOnly });
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
61 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
62 catch { } // Silently ignore access denied errors, likely nothing the user can do about it anyway
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
63 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
64
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
65 /// <summary>Updates the public list of <see cref="Shortcuts"/> with the results of the most recent scan</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
66 private void UpdateShortcutList()
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
67 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
68 // Remove event handlers while we're manipulating the list
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
69 Shortcuts.ListChanged -= Shortcuts_ListChanged;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
70
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
71 // Reset the list and add all appropriate shortcuts based on the current value of ShowAll
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
72 Shortcuts.Clear();
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
73 foreach (Shortcut shortcut in _allShortcuts)
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
74 if (shortcut.Hotkey != null || _showAll)
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
75 Shortcuts.Add(shortcut);
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
76
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
77 // Go through the list and look for duplicates
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
78 FindDuplicateShortcuts();
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
79
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
80 // Re-add event handlers
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
81 Shortcuts.ListChanged += Shortcuts_ListChanged;
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
82 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
83
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
84 /// <summary>Triggers a search for duplicate shortcuts when one of the shortcuts changes</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
85 void Shortcuts_ListChanged(object sender, ListChangedEventArgs e)
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
86 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
87 FindDuplicateShortcuts();
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
88 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
89
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
90 /// <summary>Scans for shortcuts that have duplicate hotkeys</summary>
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
91 private void FindDuplicateShortcuts()
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
92 {
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
93 Shortcuts.GroupBy(shortcut => shortcut.Hotkey).ToList().ForEach(group => group.ToList().ForEach(shortcut => shortcut.HasDuplicateHotkey = group.Count() > 1 && group.Key != null));
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
94 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
95 }
209d9210c18f It works.
Brad Greco <brad@bgreco.net>
parents:
diff changeset
96 }