-
Notifications
You must be signed in to change notification settings - Fork 6.7k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
423faf7
commit 4c1aacb
Showing
13 changed files
with
769 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
25 changes: 25 additions & 0 deletions
25
...ns/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Helpers/ApplicationActivationManager.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,25 @@ | ||
// 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.Runtime.CompilerServices; | ||
using System.Runtime.InteropServices; | ||
|
||
namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Helpers | ||
{ | ||
// Application Activation Manager Class | ||
[ComImport] | ||
[Guid("45BA127D-10A8-46EA-8AB7-56EA9078943C")] | ||
public class ApplicationActivationManager : IApplicationActivationManager | ||
{ | ||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)/*, PreserveSig*/] | ||
public extern IntPtr ActivateApplication([In] string appUserModelId, [In] string arguments, [In] ActivateOptions options, [Out] out uint processId); | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | ||
public extern IntPtr ActivateForFile([In] string appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] string verb, [Out] out uint processId); | ||
|
||
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType = MethodCodeType.Runtime)] | ||
public extern IntPtr ActivateForProtocol([In] string appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out uint processId); | ||
} | ||
} |
32 changes: 32 additions & 0 deletions
32
...s/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Helpers/IApplicationActivationManager.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,32 @@ | ||
// 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.Runtime.InteropServices; | ||
|
||
namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Helpers | ||
{ | ||
// Reference : https://github.com/MicrosoftEdge/edge-launcher/blob/108e63df0b4cb5cd9d5e45aa7a264690851ec51d/MIcrosoftEdgeLauncherCsharp/Program.cs | ||
[Flags] | ||
public enum ActivateOptions | ||
{ | ||
None = 0x00000000, | ||
DesignMode = 0x00000001, | ||
NoErrorUI = 0x00000002, | ||
NoSplashScreen = 0x00000004, | ||
} | ||
|
||
// ApplicationActivationManager | ||
[ComImport] | ||
[Guid("2e941141-7f97-4756-ba1d-9decde894a3d")] | ||
[InterfaceType(ComInterfaceType.InterfaceIsIUnknown)] | ||
public interface IApplicationActivationManager | ||
{ | ||
IntPtr ActivateApplication([In] string appUserModelId, [In] string arguments, [In] ActivateOptions options, [Out] out uint processId); | ||
|
||
IntPtr ActivateForFile([In] string appUserModelId, [In] IntPtr /*IShellItemArray* */ itemArray, [In] string verb, [Out] out uint processId); | ||
|
||
IntPtr ActivateForProtocol([In] string appUserModelId, [In] IntPtr /* IShellItemArray* */itemArray, [Out] out uint processId); | ||
} | ||
} |
13 changes: 13 additions & 0 deletions
13
...launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Helpers/ITerminalQuery.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
// 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.Collections.Generic; | ||
|
||
namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Helpers | ||
{ | ||
public interface ITerminalQuery | ||
{ | ||
IEnumerable<TerminalProfile> GetProfiles(); | ||
} | ||
} |
14 changes: 14 additions & 0 deletions
14
...launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Helpers/TerminalHelper.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,14 @@ | ||
// 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. | ||
|
||
namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Helpers | ||
{ | ||
public static class TerminalHelper | ||
{ | ||
public static string GetArguments(string profileName, bool openNewTab) | ||
{ | ||
return openNewTab ? $"--window 0 nt --profile \"{profileName}\"" : $"--profile \"{profileName}\""; | ||
} | ||
} | ||
} |
100 changes: 100 additions & 0 deletions
100
.../launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Helpers/TerminalQuery.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
// 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.Collections.ObjectModel; | ||
using System.IO; | ||
using System.Linq; | ||
using System.Security.Principal; | ||
using System.Text.Json; | ||
using Windows.Management.Deployment; | ||
|
||
namespace Microsoft.PowerToys.Run.Plugin.WindowsTerminal.Helpers | ||
{ | ||
public class TerminalQuery : ITerminalQuery | ||
{ | ||
private static ReadOnlyCollection<string> Packages => new List<string> | ||
{ | ||
"Microsoft.WindowsTerminal", | ||
"Microsoft.WindowsTerminalPreview", | ||
}.AsReadOnly(); | ||
|
||
private static IEnumerable<TerminalPackage> _terminals; | ||
|
||
public TerminalQuery() | ||
{ | ||
var user = WindowsIdentity.GetCurrent().User; | ||
var packages = new PackageManager().FindPackagesForUser(user.Value).Where(a => Packages.Contains(a.Id.Name)); | ||
|
||
var localAppDataPath = Environment.GetEnvironmentVariable("LOCALAPPDATA"); | ||
|
||
_terminals = packages.Select(p => | ||
{ | ||
var aumid = p.GetAppListEntries().Single().AppUserModelId; | ||
var version = new Version(p.Id.Version.Major, p.Id.Version.Minor, p.Id.Version.Build, p.Id.Version.Revision); | ||
var settingsPath = Path.Combine(localAppDataPath, "Packages", p.Id.FamilyName, "LocalState", "settings.json"); | ||
return new TerminalPackage(aumid, version, p.DisplayName, settingsPath); | ||
}); | ||
} | ||
|
||
public IEnumerable<TerminalProfile> GetProfiles() | ||
{ | ||
var profiles = new List<TerminalProfile>(); | ||
|
||
foreach (var terminal in _terminals) | ||
{ | ||
if (!File.Exists(terminal.SettingsPath)) | ||
{ | ||
continue; | ||
} | ||
|
||
var jsonText = File.ReadAllText(terminal.SettingsPath); | ||
|
||
var options = new JsonDocumentOptions | ||
{ | ||
CommentHandling = JsonCommentHandling.Skip, | ||
}; | ||
|
||
var json = JsonDocument.Parse(jsonText, options); | ||
|
||
json.RootElement.TryGetProperty("profiles", out JsonElement profilesElement); | ||
if (profilesElement.ValueKind != JsonValueKind.Object) | ||
{ | ||
continue; | ||
} | ||
|
||
profilesElement.TryGetProperty("list", out JsonElement profilesList); | ||
if (profilesList.ValueKind != JsonValueKind.Array) | ||
{ | ||
continue; | ||
} | ||
|
||
foreach (var profile in profilesList.EnumerateArray()) | ||
{ | ||
profiles.Add(ParseProfile(terminal, profile)); | ||
} | ||
} | ||
|
||
return profiles.OrderBy(p => p.Name); | ||
} | ||
|
||
private static TerminalProfile ParseProfile(TerminalPackage terminal, JsonElement profileElement) | ||
{ | ||
profileElement.TryGetProperty("name", out JsonElement nameElement); | ||
var name = nameElement.ValueKind == JsonValueKind.String ? nameElement.GetString() : null; | ||
|
||
profileElement.TryGetProperty("hidden", out JsonElement hiddenElement); | ||
var hidden = (hiddenElement.ValueKind == JsonValueKind.False || hiddenElement.ValueKind == JsonValueKind.True) && hiddenElement.GetBoolean(); | ||
|
||
profileElement.TryGetProperty("guid", out JsonElement guidElement); | ||
var guid = guidElement.ValueKind == JsonValueKind.String ? Guid.Parse(guidElement.GetString()) : null as Guid?; | ||
|
||
profileElement.TryGetProperty("icon", out JsonElement iconElement); | ||
var icon = iconElement.ValueKind == JsonValueKind.String ? iconElement.GetString() : null; | ||
|
||
return new TerminalProfile(terminal, name, guid, icon, hidden); | ||
} | ||
} | ||
} |
169 changes: 169 additions & 0 deletions
169
src/modules/launcher/Plugins/Microsoft.PowerToys.Run.Plugin.WindowsTerminal/Main.cs
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,169 @@ | ||
// 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 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 static PluginInitContext _context; | ||
private readonly ITerminalQuery _terminalQuery = new TerminalQuery(); | ||
private bool _openNewTab; | ||
|
||
public string Name => Resources.plugin_name; | ||
|
||
public string Description => Resources.plugin_description; | ||
|
||
public IEnumerable<PluginAdditionalOption> AdditionalOptions => new List<PluginAdditionalOption>() | ||
{ | ||
new PluginAdditionalOption() | ||
{ | ||
Key = OpenNewTab, | ||
DisplayLabel = Resources.open_new_tab, | ||
Value = false, | ||
}, | ||
}; | ||
|
||
public void Init(PluginInitContext context) | ||
{ | ||
_context = context; | ||
} | ||
|
||
public List<Result> Query(Query query) | ||
{ | ||
var search = query?.Search ?? string.Empty; | ||
var profiles = _terminalQuery.GetProfiles(); | ||
|
||
var result = new List<Result>(); | ||
|
||
foreach (var profile in profiles) | ||
{ | ||
// 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, | ||
Action = _ => | ||
{ | ||
Launch(profile.Terminal.AppUserModelId, profile.Name); | ||
return true; | ||
}, | ||
ContextData = profile, | ||
}); | ||
} | ||
} | ||
|
||
return result; | ||
} | ||
|
||
public List<ContextMenuResult> LoadContextMenus(Result selectedResult) | ||
{ | ||
if (!(selectedResult?.ContextData is TerminalProfile)) | ||
{ | ||
return new List<ContextMenuResult>(); | ||
} | ||
|
||
var result = new List<ContextMenuResult>(); | ||
|
||
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; | ||
|
||
if (settings != null && settings.AdditionalOptions != null) | ||
{ | ||
var optionConfirm = settings.AdditionalOptions.FirstOrDefault(x => x.Key == OpenNewTab); | ||
openNewTab = optionConfirm?.Value ?? false; | ||
} | ||
|
||
_openNewTab = openNewTab; | ||
} | ||
} | ||
} |
Oops, something went wrong.
4c1aacb
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@check-spelling-bot Report
Unrecognized words, please review:
Previously acknowledged words that are now absent
Accessible available chrisharris coc CTriage djsoref docsmsft dogancelik estdir Fody ftps gmx htt inprivate installpowertoys itsme listbox mfreadwrite mfuuid Nefario nitroin null nunit powertoyswiki Radiobuttons sidepanel spamming systray ulazy windevbuildagents winstore xia XSmall xunitSome files were were automatically ignored
These sample patterns would exclude them:
You should consider adding them to:
File matching is via Perl regular expressions.
To check these files, more of their words need to be in the dictionary than not. You can use
patterns.txt
to exclude portions, add items to the dictionary (e.g. by adding them toallow.txt
), or fix typos.To accept these unrecognized words as correct (and remove the previously acknowledged and now absent words), run the following commands
... in a clone of the git@github.com:microsoft/PowerToys.git repository
on the
users/davidegiacometti/terminal-plugin
branch:If you see a bunch of garbage
If it relates to a ...
well-formed pattern
See if there's a pattern that would match it.
If not, try writing one and adding it to the
patterns.txt
file.Patterns are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your lines.
Note that patterns can't match multiline strings.
binary-ish string
Please add a file path to the
excludes.txt
file instead of just accepting the garbage.File paths are Perl 5 Regular Expressions - you can test yours before committing to verify it will match your files.
^
refers to the file's path from the root of the repository, so^README\.md$
would exclude README.md (on whichever branch you're using).