microsoft/TypeAgent
Publicmirrored fromhttps://github.com/microsoft/TypeAgentAvailable
dotnet/autoShell/WindowsAppRegistry.cs
131lines · modecode
| 1 | // Copyright (c) Microsoft Corporation. |
| 2 | // Licensed under the MIT License. |
| 3 | |
| 4 | using System; |
| 5 | using System.Collections.Generic; |
| 6 | using System.IO; |
| 7 | using System.Linq; |
| 8 | using autoShell.Logging; |
| 9 | using Microsoft.WindowsAPICodePack.Shell; |
| 10 | |
| 11 | namespace autoShell; |
| 12 | |
| 13 | /// <summary> |
| 14 | /// Windows implementation of <see cref="IAppRegistry"/>. |
| 15 | /// Builds lookups from a hardcoded list of well-known apps and |
| 16 | /// dynamically discovered AppUserModelIDs from the shell AppsFolder. |
| 17 | /// </summary> |
| 18 | internal sealed class WindowsAppRegistry : IAppRegistry |
| 19 | { |
| 20 | private readonly ILogger _logger; |
| 21 | private readonly Dictionary<string, string> _friendlyNameToPath = new(StringComparer.OrdinalIgnoreCase); |
| 22 | private readonly Dictionary<string, string> _friendlyNameToId = new(StringComparer.OrdinalIgnoreCase); |
| 23 | private readonly Dictionary<string, string[]> _appMetadata; |
| 24 | |
| 25 | public WindowsAppRegistry(ILogger logger) |
| 26 | { |
| 27 | _logger = logger; |
| 28 | string userName = Environment.UserName; |
| 29 | |
| 30 | _appMetadata = new Dictionary<string, string[]>(StringComparer.OrdinalIgnoreCase) |
| 31 | { |
| 32 | { "chrome", ["chrome.exe"] }, |
| 33 | { "power point", ["C:\\Program Files\\Microsoft Office\\root\\Office16\\POWERPNT.EXE"] }, |
| 34 | { "powerpoint", ["C:\\Program Files\\Microsoft Office\\root\\Office16\\POWERPNT.EXE"] }, |
| 35 | { "word", ["C:\\Program Files\\Microsoft Office\\root\\Office16\\WINWORD.EXE"] }, |
| 36 | { "winword", ["C:\\Program Files\\Microsoft Office\\root\\Office16\\WINWORD.EXE"] }, |
| 37 | { "excel", ["C:\\Program Files\\Microsoft Office\\root\\Office16\\EXCEL.EXE"] }, |
| 38 | { "outlook", ["C:\\Program Files\\Microsoft Office\\root\\Office16\\OUTLOOK.EXE"] }, |
| 39 | { "visual studio", ["devenv.exe"] }, |
| 40 | { "visual studio code", [$"C:\\Users\\{userName}\\AppData\\Local\\Programs\\Microsoft VS Code\\Code.exe"] }, |
| 41 | { "edge", ["C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"] }, |
| 42 | { "microsoft edge", ["C:\\Program Files (x86)\\Microsoft\\Edge\\Application\\msedge.exe"] }, |
| 43 | { "notepad", ["C:\\Windows\\System32\\notepad.exe"] }, |
| 44 | { "paint", ["mspaint.exe"] }, |
| 45 | { "calculator", ["calc.exe"] }, |
| 46 | { "file explorer", ["C:\\Windows\\explorer.exe"] }, |
| 47 | { "control panel", ["C:\\Windows\\System32\\control.exe"] }, |
| 48 | { "task manager", ["C:\\Windows\\System32\\Taskmgr.exe"] }, |
| 49 | { "cmd", ["C:\\Windows\\System32\\cmd.exe"] }, |
| 50 | { "powershell", ["C:\\Windows\\System32\\WindowsPowerShell\\v1.0\\powershell.exe"] }, |
| 51 | { "snipping tool", ["C:\\Windows\\System32\\SnippingTool.exe"] }, |
| 52 | { "magnifier", ["C:\\Windows\\System32\\Magnify.exe"] }, |
| 53 | { "paint 3d", ["C:\\Program Files\\WindowsApps\\Microsoft.MSPaint_10.1807.18022.0_x64__8wekyb3d8bbwe\\"] }, |
| 54 | { "m365 copilot", ["C:\\Program Files\\WindowsApps\\Microsoft.MicrosoftOfficeHub_19.2512.45041.0_x64__8wekyb3d8bbwe\\M365Copilot.exe"] }, |
| 55 | { "copilot", ["C:\\Program Files\\WindowsApps\\Microsoft.MicrosoftOfficeHub_19.2512.45041.0_x64__8wekyb3d8bbwe\\M365Copilot.exe"] }, |
| 56 | { "spotify", ["C:\\Program Files\\WindowsApps\\SpotifyAB.SpotifyMusic_1.278.418.0_x64__zpdnekdrzrea0\\spotify.exe"] }, |
| 57 | { "github copilot", [$"{Environment.GetFolderPath(Environment.SpecialFolder.UserProfile)}\\AppData\\Local\\Microsoft\\WinGet\\Packages\\GitHub.Copilot_Microsoft.Winget.Source_8wekyb3d8bbwe\\copilot.exe", "GITHUB_COPILOT_ROOT_DIR", "--allow-all-tools"] }, |
| 58 | }; |
| 59 | |
| 60 | foreach (var kvp in _appMetadata) |
| 61 | { |
| 62 | _friendlyNameToPath.Add(kvp.Key, kvp.Value[0]); |
| 63 | } |
| 64 | |
| 65 | PopulateInstalledAppIds(); |
| 66 | } |
| 67 | |
| 68 | /// <inheritdoc/> |
| 69 | public string GetExecutablePath(string friendlyName) |
| 70 | => _friendlyNameToPath.GetValueOrDefault(friendlyName); |
| 71 | |
| 72 | /// <inheritdoc/> |
| 73 | public string GetAppUserModelId(string friendlyName) |
| 74 | => _friendlyNameToId.GetValueOrDefault(friendlyName); |
| 75 | |
| 76 | /// <inheritdoc/> |
| 77 | public string ResolveProcessName(string friendlyName) |
| 78 | { |
| 79 | string path = GetExecutablePath(friendlyName); |
| 80 | return path != null ? Path.GetFileNameWithoutExtension(path) : friendlyName; |
| 81 | } |
| 82 | |
| 83 | /// <inheritdoc/> |
| 84 | public string GetWorkingDirectoryEnvVar(string friendlyName) |
| 85 | { |
| 86 | return _appMetadata.TryGetValue(friendlyName, out string[] value) && value.Length > 1 |
| 87 | ? value[1] |
| 88 | : null; |
| 89 | } |
| 90 | |
| 91 | /// <inheritdoc/> |
| 92 | public string GetArguments(string friendlyName) |
| 93 | { |
| 94 | return _appMetadata.TryGetValue(friendlyName, out string[] value) && value.Length > 2 |
| 95 | ? string.Join(" ", value.Skip(2)) |
| 96 | : null; |
| 97 | } |
| 98 | |
| 99 | /// <inheritdoc/> |
| 100 | public IEnumerable<string> GetAllAppNames() |
| 101 | => _friendlyNameToId.Keys; |
| 102 | |
| 103 | private void PopulateInstalledAppIds() |
| 104 | { |
| 105 | // GUID taken from https://learn.microsoft.com/en-us/windows/win32/shell/knownfolderid |
| 106 | var appsFolderId = new Guid("{1e87508d-89c2-42f0-8a7e-645a0f50ca58}"); |
| 107 | |
| 108 | try |
| 109 | { |
| 110 | ShellObject appsFolder = (ShellObject)KnownFolderHelper.FromKnownFolderId(appsFolderId); |
| 111 | |
| 112 | foreach (var app in (IKnownFolder)appsFolder) |
| 113 | { |
| 114 | string appName = app.Name; |
| 115 | if (_friendlyNameToId.ContainsKey(appName)) |
| 116 | { |
| 117 | _logger.Debug("Key has multiple values: " + appName); |
| 118 | } |
| 119 | else |
| 120 | { |
| 121 | // The ParsingName property is the AppUserModelID |
| 122 | _friendlyNameToId.Add(appName, app.ParsingName); |
| 123 | } |
| 124 | } |
| 125 | } |
| 126 | catch (Exception ex) |
| 127 | { |
| 128 | _logger.Debug($"Failed to enumerate installed apps: {ex.Message}"); |
| 129 | } |
| 130 | } |
| 131 | } |
| 132 | |