Ядро приложения 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