Ядро приложения dotnet запускается как администратор
У меня есть консольное приложение dotnet, для которого требуются права администратора. Я не могу найти, как это сделать. В обычном проекте я бы добавил app.manifest и установил
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
но я не могу понять, как вставить это в сборку.
Как это сделать?
Ответы
Ответ 1
Это не поддерживается в .NET Core.
.NET Core реализует этот (расширенный) подмножество функций .NET Framework, которые, как известно, являются межплатформенными.
Приложение, запрашивающее и получающее привилегии на повышение, не поддерживается на многих платформах, отличных от Windows. Поэтому он не поддерживается .NET Core.
(Сбрасывание привилегий, с другой стороны, может поддерживаться более платформами)
Ответ 2
В ядре .NET в настоящее время app.manifest, похоже, игнорируется. Однако вы можете определить, работаете ли вы от имени администратора, и предоставить пользователю сообщение об ошибке.
Просто вызовите MainClass.RequireAdministrator()
как первую вещь в вашем методе Main. Это будет работать, чтобы выдать сообщение об ошибке в Windows и Linux, если процесс не был запущен от имени администратора /root. Вам может потребоваться добавить пакет NuGet для совместимости с Windows, чтобы он работал в Windows.
Это не вызывает повышение прав, но, по крайней мере, пользователь получает полезную ошибку, сообщающую ему, как решить проблему.
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);
}
}
}
}
Ответ 3
Как уже указывал омаджид в комментарии, в настоящее время нет способа заставить высоту.
Тем не менее, вы все равно можете управлять терминалом (Powershell, CMD и т.д.) С привилегиями администратора. Это также запустит ваше приложение с теми же привилегиями - aka - правами администратора. Мне нужно, чтобы HttpListener добавлял к нему префиксы.
Ответ 4
Чтобы расширить ответ jjxtra, если вы используете кроссплатформенность, очевидно, что его ответ не будет работать в инстансах, отличных от Windows. Я знаю... "pinvoke baaaaad", но в этом случае я думаю, что это нормально, так как нет альтернативы, о которой я знаю.
Итак, для linux/mac вы можете добавить этот код в:
private static class LinuxNative
{
[DllImport("libc")]
public static extern uint getuid();
}
var isRoot = LinuxNative.getuid() == 0;
Ответ 5
Я обнаружил, что самый простой обходной путь - это добавить файл app.manifest с настройкой, подобной настройке в приложении net Framework
<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />
затем в файл сетевого проекта ядра (.csproj в проекте С#) добавьте следующее:
<PropertyGroup>
<ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>
* Работал в консоли и WPF Netcore 3.0