Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# dotnet核心应用程序以管理员身份运行_C#_.net Core_Uac - Fatal编程技术网

C# dotnet核心应用程序以管理员身份运行

C# dotnet核心应用程序以管理员身份运行,c#,.net-core,uac,C#,.net Core,Uac,我有一个需要管理员权限才能运行的dotnet控制台应用程序。我不知道怎么做。在常规项目中,我会添加app.manifest并设置 但我不知道如何将其嵌入到构建中 如何执行此操作?这在.NET Core上不受支持 .NET核心实现了.NET Framework功能的(扩展)子集,这些功能是跨平台的 许多非Windows平台不支持请求和接收提升权限的应用程序。因此,.NET内核不支持它 (另一方面,删除权限可能会得到更多平台的支持)正如omajid在评论中指出的那样,目前没有办法强制提升。 但是,

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

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


如何执行此操作?

这在.NET Core上不受支持

.NET核心实现了.NET Framework功能的(扩展)子集,这些功能是跨平台的

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


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

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

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

只需调用
MainClass.RequireAdministrator()
,作为Main方法中的第一件事。如果进程不是以管理员/根用户身份启动的,这将在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);
            }
        }
    }
}
使用System.Runtime.InteropServices;
使用System.Security.Principal;
名称空间MyNamespace
{
公共静态类main类
{
公共静态void Main(字符串[]args)
{
RequireAdministrator();
}
[DllImport(“libc”)]
公共静态外部uint getuid();
/// 
///如果平台支持,则请求管理员权限升级,否则不执行任何操作
/// 
公共静态无效请求ReadAdministrator()
{
字符串名称=System.AppDomain.CurrentDomain.FriendlyName;
尝试
{
if(RuntimeInformation.IsOSPlatform(OSPlatform.Windows))
{
使用(WindowsIdentity=WindowsIdentity.GetCurrent())
{
WindowsPrincipal=新的WindowsPrincipal(标识);
如果(!principal.IsInRole(WindowsBuiltInRole.Administrator))
{
抛出新的InvalidOperationException($“应用程序必须以管理员身份运行。右键单击{name}文件并选择“以管理员身份运行”。”);
}
}
}
else if(getuid()!=0)
{
抛出新的InvalidOperationException($”应用程序必须以root/sudo运行。从终端,以“sudo{name}”运行可执行文件);
}
}
捕获(例外情况除外)
{
抛出新的ApplicationException(“无法确定管理员或根用户状态”,例如);
}
}
}
}

为了扩展jjxtra的答案,如果您正在跨平台运行,显然他的答案在非Windows实例中不起作用。我知道。。。“pinvoke Baaaad”,但在这种情况下,我认为没关系,因为我知道没有其他选择

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

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

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

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

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

然后在net core项目文件(.csproj in C#project)中添加以下内容:

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

应用程序清单
*在控制台和WPF netcore 3.0中工作

app.manifest
添加到您的
csproj
文件中

MyProject.csproj

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

你可能不走运。这是一个无法以一致方式跨平台提供的功能。NET Core尝试只实现在任何地方都可用的功能。添加了一个答案,说明如何在.NET Core中执行此操作,它并不完美,不会弹出提升框,但至少用户会收到一条错误消息。添加了一个答案,说明如何在.NET Core中执行此操作,它并不完美,也不会弹出提升框,但至少用户收到了一条错误消息。我猜当我写这个答案时,windows compat包不存在。请记住,它仍然只适用于Windows。这抵消了.NET Core的一个好处,即跨平台兼容性.NET Core 3.0开始支持这一点(对于WinForms和WPF)(例如@LexLi,是否有其他文档说明.NET Core 3.0将支持这一点?我一直无法从Microsoft找到任何官方信息,我有一个WPF.NET Core 3.1项目,当我按照您链接中的相同说明操作时,该项目因编译错误而失败:“属性“级别”的值在不同的清单片段中不相等。”“@TamBui类似的小事情不会出现在文档中,但GitHub问题是根据微软官方回购协议提出的,并由微软工程师做出回应,因此通常被视为官方问题。你到底犯了什么错误?您可能会问一个新问题。因此,您可以确认app.manifest在net core 3中得到尊重吗?@jjxtra是,只要您手动添加并修改csproj;如上所述,简单的答案是:只要您只在windows上运行应用程序,这与.net framework应用程序中的方法完全相同。(我可以确认这在wndows上的.net core 3.1应用程序中是有效的。)效果非常好。谢谢。
<?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>