Erik Forbes
Erik Forbes

Reputation: 35891

How can I tell if my process is running as Administrator?

I would like to display some extra UI elements when the process is being run as Administrator as opposed to when it isn't, similar to how Visual Studio 2008 displays 'Administrator' in its title bar when running as admin. How can I tell?

Upvotes: 32

Views: 20967

Answers (6)

Walter Verhoeven
Walter Verhoeven

Reputation: 4431

I hope you solved it, I was looking for someone smart to solve my NamedPipe permission issue, perhaps someone in 2022 likes my answer to your 13-year-old question...

using .net 6.0 > win7 or later ...

Perhaps do something like this and test if what you see makes sense on your account:

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 { }
    }
}

then if it does you can use something like this:

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

You could be really smart about it and make an extension method by adding the this keyword

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);
}

You could then use it like so:

WindowsIdentity.GetCurrent().Is(WellKnownSidType.AccountDomainAdminsSid))

Upvotes: 0

Soumya Mahunt
Soumya Mahunt

Reputation: 2802

I use simple try catch statement to create a random file in "C:\Windows\" folder. If it errors out the app is running with normal privileges otherwise it is running as admin privileges.

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

Upvotes: -1

Bryan Legend
Bryan Legend

Reputation: 6896

Here's a one liner to do it.

using System.Security.Principal;

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

Upvotes: 4

tbradt
tbradt

Reputation: 626

I felt it important to note the difficulty I had with attempting to use WellKnownSidType.BuiltinAdministratorsSid per casperOne's answer above. According to the WellKnownSiDType MSDN, BuiltinAdministratorsSid "Indicates a SID that matches the administrator account." So I would expect casperOne's code to work, and guess it likely does in some environments. Unfortunately, it didn't on my Windows 2003 with .NET 2.0 (legacy code). It actually returned S-1-5-32-544 which, according to this article is the sid for the Administrators group. Thus, the comparison fails for me. I will have to do my own string comparison for startswith "S-1-5-21" (that kb 243330 indicates the "21" is included even though the blog referenced above does not) and endswith "500".

Upvotes: 0

Kenn
Kenn

Reputation: 2479

I think this is a good simple mechanism.

using System.Security.Principal;

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

Upvotes: 21

casperOne
casperOne

Reputation: 74560

Technically, if you want to see if the member is the local administrator account, then you can get the security identifier (SID) of the current user through the User property on the WindowsIdentity class, like so (the static GetCurrent method gets the current Windows user):

WindowsIdentity windowsIdentity = WindowsIdentity.GetCurrent();

string sid = windowsIdentity.User.ToString();

The User property returns the SID of the user which has a number of predefined values for various groups and users.

Then you would check to see if the SID has the following pattern, indicating it is the local administrator account (which is a well-known SID):

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

Or, if you don't want to parse strings, you can use the SecurityIdentifier class:

// Get the built-in administrator account.
var sid = new SecurityIdentifier(WellKnownSidType.BuiltinAdministratorsSid, 
    null);

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

However, I suspect that what you really want to know is if the current user is a member of the administrators group for the local machine. You can get this SID using the WellKnownSidType of BuiltinAdministratorsSid:

// Get the SID of the admin group on the local machine.
var localAdminGroupSid = new SecurityIdentifier(
    WellKnownSidType.BuiltinAdministratorsSid, null);

Then you can check the Groups property on the WindowsIdentity of the user to see if that user is a member of the local admin group, like so:

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

Upvotes: 35

Related Questions