Skip to content
1 change: 1 addition & 0 deletions Flow.Launcher/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
<KeyBinding Key="Home" Modifiers="Alt" Command="{Binding SelectFirstResultCommand}"></KeyBinding>
<KeyBinding Key="O" Modifiers="Ctrl" Command="{Binding LoadContextMenuCommand}"></KeyBinding>
<KeyBinding Key="H" Modifiers="Ctrl" Command="{Binding LoadHistoryCommand}"></KeyBinding>
<KeyBinding Key="Enter" Modifiers="Ctrl+Shift" Command="{Binding OpenResultCommand}"></KeyBinding>
<KeyBinding Key="Enter" Modifiers="Shift" Command="{Binding LoadContextMenuCommand}"></KeyBinding>
<KeyBinding Key="Enter" Command="{Binding OpenResultCommand}"></KeyBinding>
<KeyBinding Key="Enter" Modifiers="Ctrl" Command="{Binding OpenResultCommand}"></KeyBinding>
Expand Down
23 changes: 22 additions & 1 deletion Plugins/Flow.Launcher.Plugin.Explorer/Search/ResultManager.cs
Original file line number Diff line number Diff line change
@@ -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
Expand Down Expand Up @@ -127,7 +129,26 @@ internal static Result CreateFileResult(string filePath, Query query, int score
{
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);
}
Expand Down
77 changes: 76 additions & 1 deletion Plugins/Flow.Launcher.Plugin.Program/Programs/UWP.cs
Original file line number Diff line number Diff line change
Expand Up @@ -267,6 +267,7 @@ public class Application : IProgram
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; }
Expand Down Expand Up @@ -320,7 +321,27 @@ public Result Result(string query, IPublicAPI api)
ContextData = this,
Action = e =>
{
Launch(api);
var elevated = (
e.SpecialKeyState.CtrlPressed &&
e.SpecialKeyState.ShiftPressed &&
!e.SpecialKeyState.AltPressed &&
!e.SpecialKeyState.WinPressed
);

if (elevated)
{
if (!CanRunElevated)
{
return false;
}

LaunchElevated();
}
else
{
Launch(api);
}

return true;
}
};
Expand Down Expand Up @@ -354,6 +375,21 @@ public List<Result> ContextMenus(IPublicAPI api)
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;
}

Expand All @@ -377,6 +413,20 @@ await Task.Run(() =>
});
}

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
Expand All @@ -403,6 +453,31 @@ public Application(AppxPackageHelper.IAppxManifestApplication manifestApp, UWP p
LogoPath = LogoPathFromUri(LogoUri);

Enabled = true;
CanRunElevated = CanApplicationRunElevated();
}

private bool CanApplicationRunElevated()
{
if (EntryPoint == "Windows.FullTrustApplication")
{
return true;
}
else
{
var manifest = Package.Location + "\\AppxManifest.xml";
if (File.Exists(manifest))
{
var file = File.ReadAllText(manifest);

// Using OrdinalIgnoreCase since this is used internally
if (file.Contains("TrustLevel=\"mediumIL\"", StringComparison.OrdinalIgnoreCase))
{
return true;
}
}
}

return false;
}

internal string ResourceFromPri(string packageFullName, string packageName, string rawReferenceValue)
Expand Down
14 changes: 11 additions & 3 deletions Plugins/Flow.Launcher.Plugin.Program/Programs/Win32.cs
Original file line number Diff line number Diff line change
Expand Up @@ -102,16 +102,24 @@ public Result Result(string query, IPublicAPI api)
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;
}
Expand Down