如何判断我的进程是否以管理员身份运行?

32

我希望在以管理员身份运行进程时显示一些额外的UI元素,而不是在没有以管理员身份运行时显示,类似于Visual Studio 2008在以管理员身份运行时在标题栏中显示“管理员”。我如何知道是否以管理员身份运行?


答案是一样的: https://dev59.com/LHVD5IYBdhLWcg3wE3bz - dso
还可以在这里查看:http://www.blackwasp.co.uk/CheckAdmin.aspx - NoWar
6个回答

35

从技术上讲,如果您想查看成员是否为本地管理员"account",则可以通过User属性WindowsIdentity上获取当前用户的security identifier (SID),如下所示(静态GetCurrent方法获取当前Windows用户):

WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();

string sid = windowsIdentity.User.ToString();
User属性返回用户的SID,对于各种组和用户都有一些预定义值
然后,您将检查SID是否具有以下模式,指示它是本地管理员帐户(这是一个众所周知的SID)

S-1-5-{other SID parts}-500

或者,如果您不想解析字符串,则可以使用SecurityIdentifier类:
// Get the built-in administrator account.
var sid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, 
    null);

// Compare to the current user.
bool isBuiltInAdmin = (windowsIdentity.User == sid);

然而,我怀疑你真正想知道的是当前用户是否是本地计算机管理员组的成员。您可以使用BuiltinAdministratorsSidWellKnownSidType来获取此SID:
// Get the SID of the admin group on the local machine.
var localAdminGroupSid = new SecurityIdentifier(
    WellKnownSidType.BuiltinAdministratorsSid, null);

然后,您可以检查用户的WindowsIdentity上的Groups属性,以查看该用户是否是本地管理员组的成员,就像这样:

bool isLocalAdmin = windowsIdentity.Groups.
    Select(g => (SecurityIdentifier) g.Translate(typeof(SecurityIdentifier))).
    Any(s => s == localAdminGroupSid);

2
这个代码段是否检查当前用户是否为管理员或进程是否正在以管理员身份运行?即使不是管理员,用户仍然可以通过右键单击进程并选择“以管理员身份运行”来以管理员身份运行进程。 - Jan Tacci
1
如果用户右键单击并选择以管理员身份运行,则该进程将作为从 UAC 对话框中选择的管理员组中的用户运行,此时该进程不会在已登录的用户下运行。 - casperOne
2
成为管理员和以管理员身份运行应用程序是两码事。即使我是管理员,我仍然可以不具备特权地运行应用程序,这在我的情况下会给我带来问题。 - João Serra
当进程在UAC下运行时,无法确定用户是否为管理员- http://i.imgur.com/6sCZ2b2.png - 但它确实回答了OP最初的问题,即是否以管理员身份运行。我将其放在这里,供那些可能寻找如何无条件检测用户是否为管理员的好答案的人参考(这也是我所寻找的)。 - ferventcoder

21

我认为这是一个不错的简单机制。

using System.Security.Principal;

WindowsIdentity identity = WindowsIdentity.GetCurrent();
WindowsPrincipal principal = new WindowsPrincipal(identity);
bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

4
这里有一行代码可以完成它。
using System.Security.Principal;

static bool IsElevated => new WindowsPrincipal(WindowsIdentity.GetCurrent()).IsInRole(WindowsBuiltInRole.Administrator);

如何在 other_process.exe 中执行,而不是当前应用程序? - T.Todua

0

希望你已经解决了问题,我一直在寻找聪明的人来解决我的NamedPipe权限问题,也许2022年有人会喜欢我的答案回答你13年前的问题...

使用 .net 6.0 > win7 或更高版本...

也许可以尝试像这样做,并测试一下你的账户是否合理:

var user = WindowsIdentity.GetCurrent();
if (user is not null)
{

    logger.LogInformation("{User}", user.Name);
    foreach (var item in Enum.GetValues<WellKnownSidType>())
    {
        try
        {
            var sid = new SecurityIdentifier(item, user.Owner);
            logger.LogInformation($"IsIsWellKnown({item}): {user.Claims.Any(a=> a.Value == sid.Value)}");
        }
        catch { }
    }
}

然后如果它确实这样做,您可以使用类似于以下内容的东西:

public static bool Is(WindowsIdentity user, WellKnownSidType type)
{
    var sid = new SecurityIdentifier(type, user.Owner);
    return user.Claims.Any(a => a.Value == sid.Value);
}

你可以很聪明地通过添加this关键字来创建一个扩展方法

public static bool Is(this WindowsIdentity user, WellKnownSidType type)
{
    var sid = new SecurityIdentifier(type, user.Owner);
    return user.Claims.Any(a => a.Value == sid.Value);
}

你可以这样使用它:
WindowsIdentity.GetCurrent().Is(WellKnownSidType.AccountDomainAdminsSid))

0

我认为有必要指出我在尝试使用 WellKnownSidType.BuiltinAdministratorsSid 时遇到的困难,这是根据 casperOne 上面的回答。根据 WellKnownSiDType MSDN,BuiltinAdministratorsSid "表示与管理员帐户匹配的 SID"。因此,我期望 casperOne 的代码能够正常工作,并且猜测它在某些环境中可能确实有效。不幸的是,在我的 Windows 2003 上,.NET 2.0(旧代码)上并没有起作用。它实际上返回了 S-1-5-32-544,而根据 this article,这是 Administrators group 的 sid。因此,比较对我来说失败了。我将不得不进行自己的字符串比较,以便以 "S-1-5-21" 开头(即使上面引用的博客没有包括 "21",但 kb 243330 表明已经包括),并以 "500" 结尾。


-1

我使用简单的try catch语句在"C:\Windows\"文件夹中创建一个随机文件。如果出错,则应用程序以普通权限运行,否则以管理员权限运行。

        try
        {
            File.Create(string.Format(@"C:\Windows\{0}.txt", new Guid()), 0, FileOptions.DeleteOnClose);
            // Do as admin
        }
        catch
        {
            // Do as default
        }

如果用户账户控制(UAC)被禁用或设置为最低级别,这将成功。 - Sanket Tarun Shah
将异常用于非异常行为是一种反模式。 - Erik Forbes

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接