From 205081504c43f6d7404ce1af008d9456fcfcc2c2 Mon Sep 17 00:00:00 2001 From: Roy Date: Mon, 17 Aug 2020 20:03:10 +0200 Subject: [PATCH 1/6] Implemented possibility to add commandline arguments in the Program Plugin --- .../ProgramArgumentParserTests.cs | 54 +++++++++++++++++++ .../Programs/Win32Tests.cs | 2 +- .../Interface/IProgramArgumentParser.cs | 15 ++++++ .../Plugins/Microsoft.Plugin.Program/Main.cs | 47 +++++++++++----- .../Microsoft.Plugin.Program.csproj | 40 +++++++------- .../DoubleDashProgramArgumentParser.cs | 43 +++++++++++++++ .../InferedProgramArgumentParser.cs | 43 +++++++++++++++ .../NoArgumentsArgumentParser.cs | 20 +++++++ .../Programs/IProgram.cs | 2 +- .../Programs/UWPApplication.cs | 9 ++-- .../Programs/Win32Program.cs | 5 +- 11 files changed, 238 insertions(+), 42 deletions(-) create mode 100644 src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs create mode 100644 src/modules/launcher/Plugins/Microsoft.Plugin.Program/Interface/IProgramArgumentParser.cs create mode 100644 src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs create mode 100644 src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs create mode 100644 src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/NoArgumentsArgumentParser.cs diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs new file mode 100644 index 000000000000..ea4f8125e1ea --- /dev/null +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs @@ -0,0 +1,54 @@ +// 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 Microsoft.Plugin.Program.ProgramArgumentParser; +using NUnit.Framework; +using Wox.Plugin; + +namespace Microsoft.Plugin.Program.UnitTests.ProgramArgumentParser +{ + [TestFixture] + public class ProgramArgumentParserTests + { + [TestCase("Microsoft Edge", "Microsoft Edge", null)] + [TestCase("Microsoft Edge ---inprivate", "Microsoft Edge ---inprivate", null)] + [TestCase("Microsoft Edge -- -inprivate", "Microsoft Edge", "-inprivate")] + [TestCase("Microsoft Edge -inprivate", "Microsoft Edge", "-inprivate")] + [TestCase("Microsoft Edge /inprivate", "Microsoft Edge", "/inprivate")] + [TestCase("edge.exe --inprivate", "edge.exe", "--inprivate")] + [TestCase("edge.exe -- --inprivate", "edge.exe", "--inprivate")] + [TestCase("edge.exe", "edge.exe", null)] + [TestCase("edge", "edge", null)] + [TestCase("cmd -c \"ping 1.1.1.1\"", "cmd", "-c \"ping 1.1.1.1\"")] + public void ProgramArgumentParserTestsCanParseQuery(string inputQuery, string expectedProgram, string expectedProgramArguments) + { + // Arrange + var argumentParsers = new IProgramArgumentParser[] + { + new DoubleDashProgramArgumentParser(), + new InferedProgramArgumentParser(), + new NoArgumentsArgumentParser(), + }; + + // Basis version oft he Quey parser which can be found at Wox.Core.Plugin.QueryBuilder but didn't want to conenct this to that project + var splittedSearchString = inputQuery?.Split(Query.TermSeparator, System.StringSplitOptions.RemoveEmptyEntries); + var cleanQuery = string.Join(Query.TermSeparator, splittedSearchString); + var query = new Query(cleanQuery, cleanQuery, splittedSearchString, string.Empty); + + // Act + string program = null, programArguments = null; + foreach (var argumentParser in argumentParsers) + { + if (argumentParser.TryParse(query, out program, out programArguments)) + { + break; + } + } + + // Assert + Assert.AreEqual(expectedProgram, program); + Assert.AreEqual(expectedProgramArguments, programArguments); + } + } +} diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Programs/Win32Tests.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Programs/Win32Tests.cs index 8f59814ba368..2268bb930bbb 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Programs/Win32Tests.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/Programs/Win32Tests.cs @@ -434,7 +434,7 @@ public void Win32AppsShouldSetNameAsTitleWhileCreatingResult() StringMatcher.Instance = new StringMatcher(); // Act - var result = _cmderRunCommand.Result("cmder", mock.Object); + var result = _cmderRunCommand.Result("cmder", string.Empty, mock.Object); // Assert Assert.IsTrue(result.Title.Equals(_cmderRunCommand.Name, StringComparison.Ordinal)); diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Interface/IProgramArgumentParser.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Interface/IProgramArgumentParser.cs new file mode 100644 index 000000000000..354ed249f92a --- /dev/null +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Interface/IProgramArgumentParser.cs @@ -0,0 +1,15 @@ +// 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 Wox.Plugin; + +namespace Microsoft.Plugin.Program +{ + public interface IProgramArgumentParser + { + bool Enabled { get; } + + bool TryParse(Query query, out string program, out string programArguments); + } +} diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs index a5a35e744039..ef1a003b9ea0 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation +// 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. @@ -7,6 +7,7 @@ using System.Diagnostics; using System.Linq; using System.Threading.Tasks; +using Microsoft.Plugin.Program.ProgramArgumentParser; using Microsoft.Plugin.Program.Programs; using Microsoft.Plugin.Program.Storage; using Wox.Infrastructure.Logger; @@ -18,6 +19,13 @@ namespace Microsoft.Plugin.Program { public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable, IDisposable { + private static readonly IProgramArgumentParser[] _programArgumentParsers = new IProgramArgumentParser[] + { + new DoubleDashProgramArgumentParser(), + new InferedProgramArgumentParser(), + new NoArgumentsArgumentParser(), + }; + internal static ProgramPluginSettings Settings { get; set; } private static PluginInitContext _context; @@ -60,22 +68,35 @@ public void Save() public List Query(Query query) { - var results1 = _win32ProgramRepository.AsParallel() - .Where(p => p.Enabled) - .Select(p => p.Result(query.Search, _context.API)); + foreach (var programArgumentParser in _programArgumentParsers) + { + if (!programArgumentParser.Enabled) + { + continue; + } + + if (!programArgumentParser.TryParse(query, out var program, out var programArguments)) + { + continue; + } - var results2 = _packageRepository.AsParallel() - .Where(p => p.Enabled) - .Select(p => p.Result(query.Search, _context.API)); + var results1 = _win32ProgramRepository.AsParallel() + .Where(p => p.Enabled) + .Select(p => p.Result(program, programArguments, _context.API)); - var result = results1.Concat(results2).Where(r => r != null && r.Score > 0); - if (result.Any()) - { - var maxScore = result.Max(x => x.Score); - result = result.Where(x => x.Score > Settings.MinScoreThreshold * maxScore); + var results2 = _packageRepository.AsParallel() + .Where(p => p.Enabled) + .Select(p => p.Result(program, programArguments, _context.API)); + + var result = results1.Concat(results2).Where(r => r != null && r.Score > 0); + if (result.Any()) + { + var maxScore = result.Max(x => x.Score); + result = result.Where(x => x.Score > Settings.MinScoreThreshold * maxScore); + } } - return result.ToList(); + return new List(0); } public void Init(PluginInitContext context) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj index f98c50abd9b9..2a30aeb82b52 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Microsoft.Plugin.Program.csproj @@ -1,4 +1,4 @@ - + @@ -43,11 +43,11 @@ true - - - - - + + + + + @@ -63,9 +63,9 @@ - - all - runtime; build; native; contentfiles; analyzers; buildtransitive + + all + runtime; build; native; contentfiles; analyzers; buildtransitive @@ -127,17 +127,17 @@ all - - - True - True - Resources.resx - + + + True + True + Resources.resx + - - - PublicResXFileCodeGenerator - Resources.Designer.cs - + + + PublicResXFileCodeGenerator + Resources.Designer.cs + \ No newline at end of file diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs new file mode 100644 index 000000000000..880e6ed442fc --- /dev/null +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs @@ -0,0 +1,43 @@ +// 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.Linq; +using Wox.Plugin; + +namespace Microsoft.Plugin.Program +{ + public class DoubleDashProgramArgumentParser : IProgramArgumentParser + { + private const string DoubleDash = "--"; + + public bool Enabled { get; } = true; + + public bool TryParse(Query query, out string program, out string programArguments) + { + if (!string.IsNullOrEmpty(query?.Search)) + { + // First Argument is always (part of) the programa, 2nd term is possibly a Program Argument + if (query.Terms.Length > 1) + { + for (var i = 1; i < query.Terms.Length; i++) + { + if (!string.Equals(query.Terms[i], DoubleDash, StringComparison.Ordinal)) + { + continue; + } + + program = string.Join(Query.TermSeparator, query.Terms.Take(i)); + programArguments = string.Join(Query.TermSeparator, query.Terms.Skip(i + 1)); + return true; + } + } + } + + program = null; + programArguments = null; + return false; + } + } +} diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs new file mode 100644 index 000000000000..94eba3370aae --- /dev/null +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs @@ -0,0 +1,43 @@ +// 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.Linq; +using System.Text.RegularExpressions; +using Wox.Plugin; + +namespace Microsoft.Plugin.Program +{ + public class InferedProgramArgumentParser : IProgramArgumentParser + { + private static readonly Regex ArgumentPrefixRegex = new Regex("^(-|--|/)[a-zA-Z]+", RegexOptions.Compiled); + + public bool Enabled { get; } = true; + + public bool TryParse(Query query, out string program, out string programArguments) + { + if (!string.IsNullOrEmpty(query?.Search)) + { + // First Argument is always (part of) the programa, 2nd term is possibly a Program Argument + if (query.Terms.Length > 1) + { + for (var i = 1; i < query.Terms.Length; i++) + { + if (!ArgumentPrefixRegex.IsMatch(query.Terms[i])) + { + continue; + } + + program = string.Join(Query.TermSeparator, query.Terms.Take(i)); + programArguments = string.Join(Query.TermSeparator, query.Terms.Skip(i)); + return true; + } + } + } + + program = null; + programArguments = null; + return false; + } + } +} diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/NoArgumentsArgumentParser.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/NoArgumentsArgumentParser.cs new file mode 100644 index 000000000000..d0a07755d5c6 --- /dev/null +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/NoArgumentsArgumentParser.cs @@ -0,0 +1,20 @@ +// 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 Wox.Plugin; + +namespace Microsoft.Plugin.Program.ProgramArgumentParser +{ + public class NoArgumentsArgumentParser : IProgramArgumentParser + { + public bool Enabled { get; } = true; + + public bool TryParse(Query query, out string program, out string programArguments) + { + program = query?.Search; + programArguments = null; + return true; + } + } +} diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/IProgram.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/IProgram.cs index 5f55ff6d28e8..ac59f1229999 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/IProgram.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/IProgram.cs @@ -11,7 +11,7 @@ public interface IProgram { List ContextMenus(IPublicAPI api); - Result Result(string query, IPublicAPI api); + Result Result(string query, string queryArguments, IPublicAPI api); string UniqueIdentifier { get; set; } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs index 14003639a570..c9e0275168c6 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs @@ -79,7 +79,7 @@ private static string SetSubtitle() return Properties.Resources.powertoys_run_plugin_program_packaged_application; } - public Result Result(string query, IPublicAPI api) + public Result Result(string query, string queryArguments, IPublicAPI api) { if (api == null) { @@ -100,7 +100,7 @@ public Result Result(string query, IPublicAPI api) ContextData = this, Action = e => { - Launch(api); + Launch(api, queryArguments); return true; }, }; @@ -195,16 +195,15 @@ public List ContextMenus(IPublicAPI api) } [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Intentially keeping the process alive, and showing the user an error message")] - private async void Launch(IPublicAPI api) + private async void Launch(IPublicAPI api, string queryArguments) { var appManager = new ApplicationActivationHelper.ApplicationActivationManager(); - const string noArgs = ""; const ApplicationActivationHelper.ActivateOptions noFlags = ApplicationActivationHelper.ActivateOptions.None; await Task.Run(() => { try { - appManager.ActivateApplication(UserModelId, noArgs, noFlags, out uint unusedPid); + appManager.ActivateApplication(UserModelId, queryArguments, noFlags, out var unusedPid); } catch (Exception) { diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs index 13a54a3cd2a8..133e370b6d6d 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs @@ -1,4 +1,4 @@ -// Copyright (c) Microsoft Corporation +// 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. @@ -165,7 +165,7 @@ public bool QueryEqualsNameForRunCommands(string query) return true; } - public Result Result(string query, IPublicAPI api) + public Result Result(string query, string queryArguments, IPublicAPI api) { if (api == null) { @@ -211,6 +211,7 @@ public Result Result(string query, IPublicAPI api) FileName = LnkResolvedPath ?? FullPath, WorkingDirectory = ParentDirectory, UseShellExecute = true, + Arguments = queryArguments, }; Main.StartProcess(Process.Start, info); From 4b6ebb52122968893d3698f023b9323c75057d2c Mon Sep 17 00:00:00 2001 From: Roy Date: Thu, 17 Sep 2020 20:59:26 +0200 Subject: [PATCH 2/6] Add missing return statement inc ommandArgumentParser loop --- src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs index ef1a003b9ea0..3e6ff2c578a9 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs @@ -94,6 +94,8 @@ public List Query(Query query) var maxScore = result.Max(x => x.Score); result = result.Where(x => x.Score > Settings.MinScoreThreshold * maxScore); } + + return result.ToList(); } return new List(0); From a43e3a0e36092d5b074242724a35a552bf827ed1 Mon Sep 17 00:00:00 2001 From: Roy Date: Thu, 17 Sep 2020 22:13:13 +0200 Subject: [PATCH 3/6] Fix typos --- .../ProgramArgumentParser/ProgramArgumentParserTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs index ea4f8125e1ea..fa74a74d694d 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs @@ -31,7 +31,7 @@ public void ProgramArgumentParserTestsCanParseQuery(string inputQuery, string ex new NoArgumentsArgumentParser(), }; - // Basis version oft he Quey parser which can be found at Wox.Core.Plugin.QueryBuilder but didn't want to conenct this to that project + // basic version of the Quey parser which can be found at Wox.Core.Plugin.QueryBuilder but did not want to create a project reference var splittedSearchString = inputQuery?.Split(Query.TermSeparator, System.StringSplitOptions.RemoveEmptyEntries); var cleanQuery = string.Join(Query.TermSeparator, splittedSearchString); var query = new Query(cleanQuery, cleanQuery, splittedSearchString, string.Empty); From 67d9033e83e53e018e7087a48d68b87d9555610d Mon Sep 17 00:00:00 2001 From: Roy Date: Thu, 17 Sep 2020 22:45:27 +0200 Subject: [PATCH 4/6] Fix Additional Typo --- .../ProgramArgumentParser/DoubleDashProgramArgumentParser.cs | 2 +- .../ProgramArgumentParser/InferedProgramArgumentParser.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs index 880e6ed442fc..7b3728623c30 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/DoubleDashProgramArgumentParser.cs @@ -18,7 +18,7 @@ public bool TryParse(Query query, out string program, out string programArgument { if (!string.IsNullOrEmpty(query?.Search)) { - // First Argument is always (part of) the programa, 2nd term is possibly a Program Argument + // First Argument is always (part of) the program, 2nd term is possibly a Program Argument if (query.Terms.Length > 1) { for (var i = 1; i < query.Terms.Length; i++) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs index 94eba3370aae..884a4771c455 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/ProgramArgumentParser/InferedProgramArgumentParser.cs @@ -18,7 +18,7 @@ public bool TryParse(Query query, out string program, out string programArgument { if (!string.IsNullOrEmpty(query?.Search)) { - // First Argument is always (part of) the programa, 2nd term is possibly a Program Argument + // First Argument is always (part of) the program, 2nd term is possibly a Program Argument if (query.Terms.Length > 1) { for (var i = 1; i < query.Terms.Length; i++) From 557810de2c61e22b90a2629a830cf6bdff9f27d5 Mon Sep 17 00:00:00 2001 From: Roy Date: Thu, 17 Sep 2020 22:45:43 +0200 Subject: [PATCH 5/6] Changed -c to /c to make it a valid cmd argument --- .../ProgramArgumentParser/ProgramArgumentParserTests.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs index fa74a74d694d..c233217f48f9 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program.UnitTests/ProgramArgumentParser/ProgramArgumentParserTests.cs @@ -20,7 +20,7 @@ public class ProgramArgumentParserTests [TestCase("edge.exe -- --inprivate", "edge.exe", "--inprivate")] [TestCase("edge.exe", "edge.exe", null)] [TestCase("edge", "edge", null)] - [TestCase("cmd -c \"ping 1.1.1.1\"", "cmd", "-c \"ping 1.1.1.1\"")] + [TestCase("cmd /c \"ping 1.1.1.1\"", "cmd", "/c \"ping 1.1.1.1\"")] public void ProgramArgumentParserTestsCanParseQuery(string inputQuery, string expectedProgram, string expectedProgramArguments) { // Arrange From 33f95ac0cc075a4488ac72aeba693a92f811020a Mon Sep 17 00:00:00 2001 From: Roy Date: Thu, 17 Sep 2020 22:59:02 +0200 Subject: [PATCH 6/6] Added small comment about importance of order in _programArgumentParsers --- src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs index 3e6ff2c578a9..8ce622dc7ac1 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs @@ -19,6 +19,8 @@ namespace Microsoft.Plugin.Program { public class Main : IPlugin, IPluginI18n, IContextMenu, ISavable, IReloadable, IDisposable { + // The order of this array is important! The Parsers will be checked in order (index 0 to index Length-1) and the first parser which is able to parse the Query will be used + // NoArgumentsArgumentParser does always succeed and therefor should always be last/fallback private static readonly IProgramArgumentParser[] _programArgumentParsers = new IProgramArgumentParser[] { new DoubleDashProgramArgumentParser(),