From 29ed39c7ae6c9868a738c7bbc9928a278fcbc17b Mon Sep 17 00:00:00 2001 From: Roy Date: Wed, 21 Oct 2020 20:49:55 +0200 Subject: [PATCH] Enable starting apps with command line arguments when run as admin is selected (#6923) * Enable Run as Admin Arguments * Use a seperate function for both methods which were generating ProcessStartInfo fixes missing LnkResolvedPath missing in contextmenu (E.g. Shortcuts / PWA's). * Update tests * Move ProgramArguments to Result class Co-authored-by: Roy --- .../Programs/Win32Tests.cs | 31 +++++++++++++----- .../Plugins/Microsoft.Plugin.Program/Main.cs | 4 +-- .../Programs/IProgram.cs | 2 +- .../Programs/UWPApplication.cs | 5 +-- .../Programs/Win32Program.cs | 32 +++++++++---------- src/modules/launcher/Wox.Plugin/Result.cs | 2 ++ 6 files changed, 47 insertions(+), 29 deletions(-) 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 0cea47aa2d..8aa564119f 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 @@ -439,7 +439,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _pinnedWebpage.ContextMenus(mock.Object); + List contextMenuResults = _pinnedWebpage.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(3, contextMenuResults.Count); @@ -455,7 +455,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _dummyInternetShortcutApp.ContextMenus(mock.Object); + List contextMenuResults = _dummyInternetShortcutApp.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(2, contextMenuResults.Count); @@ -470,7 +470,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _chrome.ContextMenus(mock.Object); + List contextMenuResults = _chrome.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(3, contextMenuResults.Count); @@ -486,7 +486,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _cmdRunCommand.ContextMenus(mock.Object); + List contextMenuResults = _cmdRunCommand.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(3, contextMenuResults.Count); @@ -502,7 +502,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _dummyAppRefApp.ContextMenus(mock.Object); + List contextMenuResults = _dummyAppRefApp.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(3, contextMenuResults.Count); @@ -518,7 +518,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _dummyShortcutApp.ContextMenus(mock.Object); + List contextMenuResults = _dummyShortcutApp.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(3, contextMenuResults.Count); @@ -534,7 +534,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _dummyFolderApp.ContextMenus(mock.Object); + List contextMenuResults = _dummyFolderApp.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(2, contextMenuResults.Count); @@ -549,7 +549,7 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs var mock = new Mock(); // Act - List contextMenuResults = _dummyGenericFileApp.ContextMenus(mock.Object); + List contextMenuResults = _dummyGenericFileApp.ContextMenus(string.Empty, mock.Object); // Assert Assert.AreEqual(2, contextMenuResults.Count); @@ -586,5 +586,20 @@ namespace Microsoft.Plugin.Program.UnitTests.Programs // Act return Win32Program.GetAppTypeFromPath(path); } + + [TestCase(null)] + [TestCase("")] + [TestCase("ping 1.1.1.1")] + public void EmptyArgumentsShouldNotThrow(string argument) + { + // Arrange + var mock = new Mock(); + + // Act + List contextMenuResults = _dummyInternetShortcutApp.ContextMenus(argument, mock.Object); + + // Assert (Should always return if the above does not throw any exception) + Assert.True(true); + } } } diff --git a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs index 89546c93f0..239f77263e 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Main.cs @@ -156,9 +156,9 @@ namespace Microsoft.Plugin.Program } var menuOptions = new List(); - if (selectedResult.ContextData is Programs.IProgram program) + if (selectedResult.ContextData is IProgram program) { - menuOptions = program.ContextMenus(_context.API); + menuOptions = program.ContextMenus(selectedResult.ProgramArguments, _context.API); } return menuOptions; 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 b33053fe93..0b2ef729fc 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/IProgram.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/IProgram.cs @@ -9,7 +9,7 @@ namespace Microsoft.Plugin.Program.Programs { public interface IProgram { - List ContextMenus(IPublicAPI api); + List ContextMenus(string queryArguments, IPublicAPI api); Result Result(string query, string queryArguments, IPublicAPI api); 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 1cec7be9df..f60031f6f8 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/UWPApplication.cs @@ -98,6 +98,7 @@ namespace Microsoft.Plugin.Program.Programs Icon = Logo, Score = score, ContextData = this, + ProgramArguments = queryArguments, Action = e => { Launch(api, queryArguments); @@ -117,7 +118,7 @@ namespace Microsoft.Plugin.Program.Programs } [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Intentially keeping the process alive.")] - public List ContextMenus(IPublicAPI api) + public List ContextMenus(string queryArguments, IPublicAPI api) { if (api == null) { @@ -144,7 +145,7 @@ namespace Microsoft.Plugin.Program.Programs var info = ShellCommand.SetProcessStartInfo(command, verb: "runas"); info.UseShellExecute = true; - + info.Arguments = queryArguments; Process.Start(info); return true; }, 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 eacf494548..980e8a6a0c 100644 --- a/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs +++ b/src/modules/launcher/Plugins/Microsoft.Plugin.Program/Programs/Win32Program.cs @@ -220,15 +220,10 @@ namespace Microsoft.Plugin.Program.Programs IcoPath = IcoPath, Score = score, ContextData = this, + ProgramArguments = queryArguments, Action = e => { - var info = new ProcessStartInfo - { - FileName = LnkResolvedPath ?? FullPath, - WorkingDirectory = ParentDirectory, - UseShellExecute = true, - Arguments = queryArguments, - }; + var info = GetProcessStartInfo(queryArguments); Main.StartProcess(Process.Start, info); @@ -248,7 +243,7 @@ namespace Microsoft.Plugin.Program.Programs } [System.Diagnostics.CodeAnalysis.SuppressMessage("Design", "CA1031:Do not catch general exception types", Justification = "Intentially keeping the process alive.")] - public List ContextMenus(IPublicAPI api) + public List ContextMenus(string queryArguments, IPublicAPI api) { if (api == null) { @@ -269,14 +264,7 @@ namespace Microsoft.Plugin.Program.Programs AcceleratorModifiers = ModifierKeys.Control | ModifierKeys.Shift, Action = _ => { - var info = new ProcessStartInfo - { - FileName = FullPath, - WorkingDirectory = ParentDirectory, - Verb = "runas", - UseShellExecute = true, - }; - + var info = GetProcessStartInfo(queryArguments, true); Task.Run(() => Main.StartProcess(Process.Start, info)); return true; @@ -327,6 +315,18 @@ namespace Microsoft.Plugin.Program.Programs return contextMenus; } + private ProcessStartInfo GetProcessStartInfo(string programArguments, bool runAsAdmin = false) + { + return new ProcessStartInfo + { + FileName = LnkResolvedPath ?? FullPath, + WorkingDirectory = ParentDirectory, + UseShellExecute = true, + Arguments = programArguments, + Verb = runAsAdmin ? "runas" : string.Empty, + }; + } + public override string ToString() { return ExecutableName; diff --git a/src/modules/launcher/Wox.Plugin/Result.cs b/src/modules/launcher/Wox.Plugin/Result.cs index ea3bb5b4f3..6e4ecd06b2 100644 --- a/src/modules/launcher/Wox.Plugin/Result.cs +++ b/src/modules/launcher/Wox.Plugin/Result.cs @@ -36,6 +36,8 @@ namespace Wox.Plugin public string FontFamily { get; set; } + public string ProgramArguments { get; set; } + public Visibility ToolTipVisibility { get; set; } = Visibility.Collapsed; public ToolTipData ToolTipData