// Copyright (c) Microsoft Corporation // The Microsoft Corporation licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Collections.Generic; using System.Linq; using System.Windows.Controls; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Helpers; using Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Properties; using Microsoft.PowerToys.Settings.UI.Library; using Wox.Infrastructure; using Wox.Plugin; using Wox.Plugin.Logger; namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal { public class Main : IPlugin, IContextMenu, IPluginI18n, ISettingProvider { private const string OpenNewTab = nameof(OpenNewTab); private const string ShowHiddenProfiles = nameof(ShowHiddenProfiles); private readonly ITerminalQuery _terminalQuery = new TerminalQuery(); private PluginInitContext _context; private bool _openNewTab; private bool _showHiddenProfiles; private Dictionary _logoCache = new Dictionary(); public string Name => Resources.plugin_name; public string Description => Resources.plugin_description; public IEnumerable AdditionalOptions => new List() { new PluginAdditionalOption() { Key = OpenNewTab, DisplayLabel = Resources.open_new_tab, Value = false, }, new PluginAdditionalOption() { Key = ShowHiddenProfiles, DisplayLabel = Resources.show_hidden_profiles, Value = false, }, }; public void Init(PluginInitContext context) { _context = context; } public List Query(Query query) { var search = query?.Search ?? string.Empty; var profiles = _terminalQuery.GetProfiles(); var result = new List(); foreach (var profile in profiles) { if (profile.Hidden && !_showHiddenProfiles) { continue; } // Action keyword only or search query match if ((!string.IsNullOrWhiteSpace(query.ActionKeyword) && string.IsNullOrWhiteSpace(search)) || StringMatcher.FuzzySearch(search, profile.Name).Success) { result.Add(new Result { Title = profile.Name, SubTitle = profile.Terminal.DisplayName, Icon = () => GetLogo(profile.Terminal), Action = _ => { Launch(profile.Terminal.AppUserModelId, profile.Name); return true; }, ContextData = profile, }); } } return result; } public List LoadContextMenus(Result selectedResult) { if (!(selectedResult?.ContextData is TerminalProfile)) { return new List(); } var result = new List(); if (selectedResult.ContextData is TerminalProfile profile) { result.Add(new ContextMenuResult { Title = Resources.run_as_administrator, Glyph = "\xE7EF", FontFamily = "Segoe MDL2 Assets", AcceleratorKey = Key.Enter, AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift, Action = _ => { LaunchElevated(profile.Terminal.AppUserModelId, profile.Name); return true; }, }); } return result; } public string GetTranslatedPluginTitle() { return Resources.plugin_name; } public string GetTranslatedPluginDescription() { return Resources.plugin_description; } private void Launch(string id, string profile) { var appManager = new ApplicationActivationManager(); const ActivateOptions noFlags = ActivateOptions.None; var queryArguments = TerminalHelper.GetArguments(profile, _openNewTab); try { appManager.ActivateApplication(id, queryArguments, noFlags, out var unusedPid); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { var name = "Plugin: " + Resources.plugin_name; var message = Resources.run_terminal_failed; Log.Exception("Failed to open Windows Terminal", ex, GetType()); _context.API.ShowMsg(name, message, string.Empty); } } private void LaunchElevated(string id, string profile) { try { string path = "shell:AppsFolder\\" + id; Helper.OpenInShell(path, TerminalHelper.GetArguments(profile, _openNewTab), runAsAdmin: true); } #pragma warning disable CA1031 // Do not catch general exception types catch (Exception ex) #pragma warning restore CA1031 // Do not catch general exception types { var name = "Plugin: " + Resources.plugin_name; var message = Resources.run_terminal_failed; Log.Exception("Failed to open Windows Terminal", ex, GetType()); _context.API.ShowMsg(name, message, string.Empty); } } public Control CreateSettingPanel() { throw new NotImplementedException(); } public void UpdateSettings(PowerLauncherPluginSettings settings) { var openNewTab = false; var showHiddenProfiles = false; if (settings != null && settings.AdditionalOptions != null) { openNewTab = settings.AdditionalOptions.FirstOrDefault(x => x.Key == OpenNewTab)?.Value ?? false; showHiddenProfiles = settings.AdditionalOptions.FirstOrDefault(x => x.Key == ShowHiddenProfiles)?.Value ?? false; } _openNewTab = openNewTab; _showHiddenProfiles = showHiddenProfiles; } private ImageSource GetLogo(TerminalPackage terminal) { var aumid = terminal.AppUserModelId; if (!_logoCache.ContainsKey(aumid)) { _logoCache.Add(aumid, terminal.GetLogo()); } return _logoCache[aumid]; } } }