diff --git a/Flow.Launcher/MainWindow.xaml b/Flow.Launcher/MainWindow.xaml index fcc3af5c5..83cc016bb 100644 --- a/Flow.Launcher/MainWindow.xaml +++ b/Flow.Launcher/MainWindow.xaml @@ -46,6 +46,7 @@ + diff --git a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs index 09315d9dd..7e12fea13 100644 --- a/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs +++ b/Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs @@ -1,8 +1,10 @@ using Flow.Launcher.Infrastructure; using Flow.Launcher.Plugin.SharedCommands; using System; +using System.Diagnostics; using System.IO; using System.Linq; +using System.Threading.Tasks; using System.Windows; namespace Flow.Launcher.Plugin.Explorer.Search @@ -127,7 +129,26 @@ namespace Flow.Launcher.Plugin.Explorer.Search { try { - if (c.SpecialKeyState.CtrlPressed) + if (File.Exists(filePath) && c.SpecialKeyState.CtrlPressed && c.SpecialKeyState.ShiftPressed) + { + Task.Run(() => + { + try + { + Process.Start(new ProcessStartInfo + { + FileName = filePath, + UseShellExecute = true, + Verb = "runas", + }); + } + catch (Exception e) + { + MessageBox.Show(e.Message, "Could not start " + filePath); + } + }); + } + else if (c.SpecialKeyState.CtrlPressed) { FilesFolders.OpenContainingFolder(filePath); } diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml index e00534367..770bb69cc 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml +++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/en.xaml @@ -53,5 +53,6 @@ Success Successfully disabled this program from displaying in your query + This app is not intended to be run as administrator \ No newline at end of file diff --git a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml index 550630482..eb339649f 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml +++ b/Plugins/Flow.Launcher.Plugin.Program/Languages/zh-tw.xaml @@ -33,4 +33,5 @@ 程式 在 Flow Launcher 中搜尋程式 + diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs index 869172de7..917ebe7ad 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs @@ -267,6 +267,7 @@ namespace Flow.Launcher.Plugin.Program.Programs public string Location => Package.Location; public bool Enabled { get; set; } + public bool CanRunElevated { get; set; } public string LogoUri { get; set; } public string LogoPath { get; set; } @@ -320,7 +321,29 @@ namespace Flow.Launcher.Plugin.Program.Programs ContextData = this, Action = e => { - Launch(api); + var elevated = ( + e.SpecialKeyState.CtrlPressed && + e.SpecialKeyState.ShiftPressed && + !e.SpecialKeyState.AltPressed && + !e.SpecialKeyState.WinPressed + ); + + if (elevated && CanRunElevated) + { + LaunchElevated(); + } + else + { + Launch(api); + + if (elevated) + { + var title = "Plugin: Program"; + var message = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator_not_supported_message"); + api.ShowMsg(title, message, string.Empty); + } + } + return true; } }; @@ -354,6 +377,21 @@ namespace Flow.Launcher.Plugin.Program.Programs IcoPath = "Images/folder.png" } }; + + if (CanRunElevated) + { + contextMenus.Add(new Result + { + Title = api.GetTranslation("flowlauncher_plugin_program_run_as_administrator"), + Action = _ => + { + LaunchElevated(); + return true; + }, + IcoPath = "Images/cmd.png" + }); + } + return contextMenus; } @@ -377,6 +415,20 @@ namespace Flow.Launcher.Plugin.Program.Programs }); } + private async void LaunchElevated() + { + string command = "shell:AppsFolder\\" + UniqueIdentifier; + command = Environment.ExpandEnvironmentVariables(command.Trim()); + + var info = new ProcessStartInfo(command) + { + UseShellExecute = true, + Verb = "runas", + }; + + Main.StartProcess(Process.Start, info); + } + public Application(AppxPackageHelper.IAppxManifestApplication manifestApp, UWP package) { // This is done because we cannot use the keyword 'out' along with a property @@ -403,6 +455,28 @@ namespace Flow.Launcher.Plugin.Program.Programs LogoPath = LogoPathFromUri(LogoUri); Enabled = true; + CanRunElevated = CanApplicationRunElevated(); + } + + private bool CanApplicationRunElevated() + { + if (EntryPoint == "Windows.FullTrustApplication") + { + return true; + } + + var manifest = Package.Location + "\\AppxManifest.xml"; + if (File.Exists(manifest)) + { + var file = File.ReadAllText(manifest); + + if (file.Contains("TrustLevel=\"mediumIL\"", StringComparison.OrdinalIgnoreCase)) + { + return true; + } + } + + return false; } internal string ResourceFromPri(string packageFullName, string packageName, string rawReferenceValue) diff --git a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs index 931cfacc1..9d7530856 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs +++ b/Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs @@ -102,16 +102,24 @@ namespace Flow.Launcher.Plugin.Program.Programs Score = matchResult.Score, TitleHighlightData = matchResult.MatchData, ContextData = this, - Action = _ => + Action = c => { + var runAsAdmin = ( + c.SpecialKeyState.CtrlPressed && + c.SpecialKeyState.ShiftPressed && + !c.SpecialKeyState.AltPressed && + !c.SpecialKeyState.WinPressed + ); + var info = new ProcessStartInfo { FileName = LnkResolvedPath ?? FullPath, WorkingDirectory = ParentDirectory, - UseShellExecute = true + UseShellExecute = true, + Verb = runAsAdmin ? "runas" : null }; - Main.StartProcess(Process.Start, info); + Task.Run(() => Main.StartProcess(Process.Start, info)); return true; } diff --git a/Plugins/Flow.Launcher.Plugin.Program/plugin.json b/Plugins/Flow.Launcher.Plugin.Program/plugin.json index a37075b0c..424aa04f5 100644 --- a/Plugins/Flow.Launcher.Plugin.Program/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Program/plugin.json @@ -4,7 +4,7 @@ "Name": "Program", "Description": "Search programs in Flow.Launcher", "Author": "qianlifeng", - "Version": "1.5.4", + "Version": "1.6.0", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Program.dll", diff --git a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs index 58f8538f0..0a934ab32 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/Main.cs +++ b/Plugins/Flow.Launcher.Plugin.Shell/Main.cs @@ -73,7 +73,14 @@ namespace Flow.Launcher.Plugin.Shell IcoPath = Image, Action = c => { - Execute(Process.Start, PrepareProcessStartInfo(m, c.SpecialKeyState.CtrlPressed)); + var runAsAdministrator = ( + c.SpecialKeyState.CtrlPressed && + c.SpecialKeyState.ShiftPressed && + !c.SpecialKeyState.AltPressed && + !c.SpecialKeyState.WinPressed + ); + + Execute(Process.Start, PrepareProcessStartInfo(m, runAsAdministrator)); return true; } })); @@ -106,7 +113,14 @@ namespace Flow.Launcher.Plugin.Shell IcoPath = Image, Action = c => { - Execute(Process.Start, PrepareProcessStartInfo(m.Key)); + var runAsAdministrator = ( + c.SpecialKeyState.CtrlPressed && + c.SpecialKeyState.ShiftPressed && + !c.SpecialKeyState.AltPressed && + !c.SpecialKeyState.WinPressed + ); + + Execute(Process.Start, PrepareProcessStartInfo(m.Key, runAsAdministrator)); return true; } }; @@ -129,7 +143,14 @@ namespace Flow.Launcher.Plugin.Shell IcoPath = Image, Action = c => { - Execute(Process.Start, PrepareProcessStartInfo(cmd)); + var runAsAdministrator = ( + c.SpecialKeyState.CtrlPressed && + c.SpecialKeyState.ShiftPressed && + !c.SpecialKeyState.AltPressed && + !c.SpecialKeyState.WinPressed + ); + + Execute(Process.Start, PrepareProcessStartInfo(cmd, runAsAdministrator)); return true; } }; @@ -147,7 +168,14 @@ namespace Flow.Launcher.Plugin.Shell IcoPath = Image, Action = c => { - Execute(Process.Start, PrepareProcessStartInfo(m.Key)); + var runAsAdministrator = ( + c.SpecialKeyState.CtrlPressed && + c.SpecialKeyState.ShiftPressed && + !c.SpecialKeyState.AltPressed && + !c.SpecialKeyState.WinPressed + ); + + Execute(Process.Start, PrepareProcessStartInfo(m.Key, runAsAdministrator)); return true; } }); diff --git a/Plugins/Flow.Launcher.Plugin.Shell/plugin.json b/Plugins/Flow.Launcher.Plugin.Shell/plugin.json index bccba4590..cb02f6607 100644 --- a/Plugins/Flow.Launcher.Plugin.Shell/plugin.json +++ b/Plugins/Flow.Launcher.Plugin.Shell/plugin.json @@ -4,7 +4,7 @@ "Name": "Shell", "Description": "Provide executing commands from Flow Launcher", "Author": "qianlifeng", - "Version": "1.4.3", + "Version": "1.4.4", "Language": "csharp", "Website": "https://github.com/Flow-Launcher/Flow.Launcher", "ExecuteFileName": "Flow.Launcher.Plugin.Shell.dll",