Skip to content
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