dotnet 核心应用 运行 作为管理员

dotnet core app run as administrator

我有一个 dotnet 控制台应用程序需要 运行 的管理员权限。我找不到该怎么做。在常规项目中,我会添加一个 app.manifest 并设置

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

但我不知道如何将其嵌入构建中。

我该怎么做?

.NET Core 不支持。

.NET Core 实现了已知跨平台的 .NET Framework 功能的(扩展)子集。

许多非Windows 平台不支持请求和接收提升权限的应用程序。因此.NET Core 不支持它。

(另一方面,更多平台可能支持删除权限)

正如 omajid 已经在评论中指出的那样,目前无法强制提升。 但是,您仍然可以 运行 具有管理员权限的终端(Powershell、CMD 等)。这也将 运行 您的应用程序具有相同的权限 - 即 - 管理员权限。我需要 HttpListener 为其添加前缀。

在 .NET 核心 2.X 及更早版本中,app.manifest 似乎被忽略了。但是,您可以检测您是否 运行 管理员并向用户提供错误消息。

只需调用 MainClass.RequireAdministrator() 作为 Main 方法中的第一件事。如果进程未以 administrator/root 启动,这将在 Windows 和 Linux 上给出错误消息。您可能需要添加 Windows 兼容性 NuGet 包才能在 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);
            }
        }
    }
}

为了扩展 jjxtra 的答案,如果你是 运行 跨平台的,显然他的答案在非 Windows 实例中不起作用。我知道... "pinvoke baaaaad",但在这种情况下我认为没关系,因为据我所知别无选择。

因此,对于 linux/mac,您可以将此代码添加到:

private static class LinuxNative
{
    [DllImport("libc")]
    public static extern uint getuid();
}

var isRoot = LinuxNative.getuid() == 0;

我发现最简单的解决方法是添加 app.manifest 文件,其设置类似于 net framework app

<requestedExecutionLevel level="requireAdministrator" uiAccess="false" />

然后在您的网络核心项目文件(C# 项目中的 .csproj)中添加以下内容:

<PropertyGroup>
  <ApplicationManifest>app.manifest</ApplicationManifest>
</PropertyGroup>

*在控制台和 WPF netcore 3.0 中工作

<ApplicationManifest>app.manifest</ApplicationManifest> 添加到您的 csproj 文件。

MyProject.csproj

<Project Sdk="Microsoft.NET.Sdk">    
  <PropertyGroup>
    <OutputType>Exe</OutputType>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <ApplicationManifest>app.manifest</ApplicationManifest>
  </PropertyGroup>    
</Project>

将以下 app.manifest 文件添加到您的项目中。

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>