Reputation: 2856
I have a dotnet console application that requires administrator privileges to run. I can't find how to do this. In a regular project I would add a app.manifest and set
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
but I can't figure how to embed this in the build.
How do I do this?
Upvotes: 34
Views: 25214
Reputation: 1
I found that in Visual Studio 2022 you can add an Application Manifest in the traditional manner. There is a section in project Properties that enables setting a custom manifest file if desired.
In other words, this is no longer a problem if you are targeting Windows with .NET Core.
Upvotes: 0
Reputation: 9634
Add <ApplicationManifest>app.manifest</ApplicationManifest>
to your csproj
file.
MyProject.csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType>
<TargetFramework>netcoreapp3.1</TargetFramework>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
</Project>
Add the below app.manifest
file to your project.
app.manifest
<?xml version="1.0" encoding="utf-8"?>
<assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1">
<assemblyIdentity version="1.0.0.0" name="MyApplication.app"/>
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
<security>
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
</requestedPrivileges>
</security>
</trustInfo>
</assembly>
Upvotes: 32
Reputation: 21160
In .NET core 2.X and earlier, the app.manifest appears to be ignored. However you can detect whether you are running as administrator and provide an error message to the user.
Simply call MainClass.RequireAdministrator()
as the first thing in your Main method. This will work to give an error message on Windows and Linux if the process was not started as administrator/root. You may need to add the Windows compatibility NuGet package for it to work on Windows.
This does not force elevation, but at least the user gets a helpful error telling them how to resolve the problem.
using System.Runtime.InteropServices;
using System.Security.Principal;
namespace MyNamespace
{
public static class MainClass
{
public static void Main(string[] args)
{
RequireAdministrator();
}
[DllImport("libc")]
public static extern uint getuid();
/// <summary>
/// Asks for administrator privileges upgrade if the platform supports it, otherwise does nothing
/// </summary>
public static void RequireAdministrator()
{
string name = System.AppDomain.CurrentDomain.FriendlyName;
try
{
if (RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
using (WindowsIdentity identity = WindowsIdentity.GetCurrent())
{
WindowsPrincipal principal = new WindowsPrincipal(identity);
if (!principal.IsInRole(WindowsBuiltInRole.Administrator))
{
throw new InvalidOperationException($"Application must be run as administrator. Right click the {name} file and select 'run as administrator'.");
}
}
}
else if (getuid() != 0)
{
throw new InvalidOperationException($"Application must be run as root/sudo. From terminal, run the executable as 'sudo {name}'");
}
}
catch (Exception ex)
{
throw new ApplicationException("Unable to determine administrator or root status", ex);
}
}
}
}
Upvotes: 14
Reputation: 450
I found the simplest workaround would be to add the app.manifest file with the setting like what in net framework app
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
then on your net core project file (.csproj in C# project) add the following:
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
*Worked in Console and WPF netcore 3.0
Upvotes: 30
Reputation: 13597
To extend jjxtra's answer, if you are running cross-platform, obviously his answer won't work in non-Windows instances. I know... "pinvoke baaaaad", but in this case i think it's OK since there is no alternative that i know of.
So, for linux/mac, you could add this code in:
private static class LinuxNative
{
[DllImport("libc")]
public static extern uint getuid();
}
var isRoot = LinuxNative.getuid() == 0;
Upvotes: 3
Reputation: 77
As omajid already pointed out in a comment, there is currently no way to force the elevation. You may however still be able to run the Terminal (Powershell, CMD etc.) with Administrator Privileges. That will also run your App with the same privileges - aka - Admin privileges. I needed that for the HttpListener to add prefixes to it.
Upvotes: 1
Reputation: 15223
This is not supported on .NET Core.
.NET Core implements that (extended) subset of .NET Framework features which are known to be cross-platform.
An application requesting and receiving elevate privileges is not supported on many non-Windows platforms. Hence it is not supported by .NET Core.
(Dropping privileges, on the other hand, might be supported by more platforms)
Upvotes: 7