Check if another process has admin privileges





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







1















I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.



Can you tell me what's wrong with it.



private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only

WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);

var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);

return succeed && isMember;
}
return false;
}

public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}

public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}

public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}









share|improve this question




















  • 2





    errors: 1 you must open process with access PROCESS_QUERY_LIMITED_INFORMATION but not PROCESS_QUERY_INFORMATION (you get access denied here if you not run as admin) 2 CheckTokenMembership work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors

    – RbMm
    Nov 24 '18 at 15:03













  • 6 you not debug self code at all

    – RbMm
    Nov 24 '18 at 15:11


















1















I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.



Can you tell me what's wrong with it.



private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only

WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);

var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);

return succeed && isMember;
}
return false;
}

public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}

public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}

public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}









share|improve this question




















  • 2





    errors: 1 you must open process with access PROCESS_QUERY_LIMITED_INFORMATION but not PROCESS_QUERY_INFORMATION (you get access denied here if you not run as admin) 2 CheckTokenMembership work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors

    – RbMm
    Nov 24 '18 at 15:03













  • 6 you not debug self code at all

    – RbMm
    Nov 24 '18 at 15:11














1












1








1








I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.



Can you tell me what's wrong with it.



private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only

WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);

var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);

return succeed && isMember;
}
return false;
}

public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}

public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}

public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}









share|improve this question
















I have wrote a code to check is a process running on the same machine has administrator privileges or not. But it always returns false.



Can you tell me what's wrong with it.



private static bool HasAdminPrivileges(int processId)
{
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId);
var opened = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_QUERY, out IntPtr hToken);
if (opened)
{
var token = new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); // 64 bit machine only

WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, out uint cbSidUint);
var cbSid = new IntPtr(cbSidUint);

var succeed = WinApi.CheckTokenMembership(token, cbSid, out bool isMember);

return succeed && isMember;
}
return false;
}

public class WinApi
{
public const int TOKEN_QUERY = 0X00000008;

[DllImport("advapi32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, out uint cbSid);

[DllImport("advapi32.dll", SetLastError = true)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);
}

public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400
}

public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}






windows winapi process system32 advapi32






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Nov 24 '18 at 17:41









Uwe Keim

27.7k32136216




27.7k32136216










asked Nov 24 '18 at 14:23









Grigor YeghiazaryanGrigor Yeghiazaryan

12816




12816








  • 2





    errors: 1 you must open process with access PROCESS_QUERY_LIMITED_INFORMATION but not PROCESS_QUERY_INFORMATION (you get access denied here if you not run as admin) 2 CheckTokenMembership work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors

    – RbMm
    Nov 24 '18 at 15:03













  • 6 you not debug self code at all

    – RbMm
    Nov 24 '18 at 15:11














  • 2





    errors: 1 you must open process with access PROCESS_QUERY_LIMITED_INFORMATION but not PROCESS_QUERY_INFORMATION (you get access denied here if you not run as admin) 2 CheckTokenMembership work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors

    – RbMm
    Nov 24 '18 at 15:03













  • 6 you not debug self code at all

    – RbMm
    Nov 24 '18 at 15:11








2




2





errors: 1 you must open process with access PROCESS_QUERY_LIMITED_INFORMATION but not PROCESS_QUERY_INFORMATION (you get access denied here if you not run as admin) 2 CheckTokenMembership work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors

– RbMm
Nov 24 '18 at 15:03







errors: 1 you must open process with access PROCESS_QUERY_LIMITED_INFORMATION but not PROCESS_QUERY_INFORMATION (you get access denied here if you not run as admin) 2 CheckTokenMembership work only with impersonation token.but you try pass primary token to it. 3 you not create admin sid - in single call to CreateWellKnownSid you not pass pointer to memory where this sid can be stored. 4 you not close opened handles. 5 you not check any errors

– RbMm
Nov 24 '18 at 15:03















6 you not debug self code at all

– RbMm
Nov 24 '18 at 15:11





6 you not debug self code at all

– RbMm
Nov 24 '18 at 15:11












2 Answers
2






active

oldest

votes


















4














You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); ), that makes no sense.



You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership.



You also need to close these handles with CloseHandle.



using System;
using System.Runtime.InteropServices;
...
public class WinApi
{
public const int TOKEN_DUPLICATE = 0x0002;
public const int TOKEN_QUERY = 0x00000008;
public const int SecurityImpersonation = 2;
public const int TokenImpersonation = 2;

[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);

[DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);

[DllImport("kernel32.dll", SetLastError = true)]
public static extern int GetCurrentProcessId();
[DllImport("kernel32.dll", SetLastError = true)]
public static extern int CloseHandle(IntPtr h);
}

public enum ProcessAccessFlags : uint
{
QueryInformation = 0x00000400,
QueryLimitedInformation = 0x1000
}

public enum WELL_KNOWN_SID_TYPE
{
WinBuiltinAdministratorsSid = 26
}

private static bool IsAdminGroupMember(int processId)
{
IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
if (haveToken)
{
haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
WinApi.CloseHandle(hPriToken);
}
if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
if (haveToken)
{
uint cbSid = 0;
bool isMember = false;
WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
Marshal.FreeCoTaskMem(pSid);
WinApi.CloseHandle(hImpToken);
return succeed && isMember;
}
return false;
}


[STAThread]static void Main(/*string args*/)
{

bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
}





share|improve this answer
























  • must be not ProcessAccessFlags.QueryInformation but ask only for PROCESS_QUERY_LIMITED_INFORMATION (not admin process can not open admin with ProcessAccessFlags.QueryInformation (i guess that this is equal to PROCESS_QUERY_INFORMATION. also we can call DuplicateToken without Ex here and if want be correct check that first call to CreateWellKnownSid fail with ERROR_INSUFFICIENT_BUFFER

    – RbMm
    Nov 24 '18 at 17:35











  • @RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.

    – Anders
    Nov 24 '18 at 17:46











  • It tries limited information first, then it tries the old one for XP - sorry - not note this in your code. CreateWellKnownSid - yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented

    – RbMm
    Nov 24 '18 at 17:54













  • about access - i be use dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation and call OpenProcess only once

    – RbMm
    Nov 24 '18 at 18:02








  • 1





    Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.

    – Anders
    Nov 24 '18 at 18:43





















1














I have created Process.Extensions.dll extension using solution offered by Anders



using System;
using ProcessExtensions;
using System.Diagnostics;
static void Main(string args)
{
bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
}


https://github.com/IamhereTeam/Process.Extensions.git



Process.Extensions.dll






share|improve this answer


























    Your Answer






    StackExchange.ifUsing("editor", function () {
    StackExchange.using("externalEditor", function () {
    StackExchange.using("snippets", function () {
    StackExchange.snippets.init();
    });
    });
    }, "code-snippets");

    StackExchange.ready(function() {
    var channelOptions = {
    tags: "".split(" "),
    id: "1"
    };
    initTagRenderer("".split(" "), "".split(" "), channelOptions);

    StackExchange.using("externalEditor", function() {
    // Have to fire editor after snippets, if snippets enabled
    if (StackExchange.settings.snippets.snippetsEnabled) {
    StackExchange.using("snippets", function() {
    createEditor();
    });
    }
    else {
    createEditor();
    }
    });

    function createEditor() {
    StackExchange.prepareEditor({
    heartbeatType: 'answer',
    autoActivateHeartbeat: false,
    convertImagesToLinks: true,
    noModals: true,
    showLowRepImageUploadWarning: true,
    reputationToPostImages: 10,
    bindNavPrevention: true,
    postfix: "",
    imageUploader: {
    brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
    contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
    allowUrls: true
    },
    onDemand: true,
    discardSelector: ".discard-answer"
    ,immediatelyShowMarkdownHelp:true
    });


    }
    });














    draft saved

    draft discarded


















    StackExchange.ready(
    function () {
    StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459123%2fcheck-if-another-process-has-admin-privileges%23new-answer', 'question_page');
    }
    );

    Post as a guest















    Required, but never shown

























    2 Answers
    2






    active

    oldest

    votes








    2 Answers
    2






    active

    oldest

    votes









    active

    oldest

    votes






    active

    oldest

    votes









    4














    You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); ), that makes no sense.



    You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership.



    You also need to close these handles with CloseHandle.



    using System;
    using System.Runtime.InteropServices;
    ...
    public class WinApi
    {
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_QUERY = 0x00000008;
    public const int SecurityImpersonation = 2;
    public const int TokenImpersonation = 2;

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int GetCurrentProcessId();
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int CloseHandle(IntPtr h);
    }

    public enum ProcessAccessFlags : uint
    {
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x1000
    }

    public enum WELL_KNOWN_SID_TYPE
    {
    WinBuiltinAdministratorsSid = 26
    }

    private static bool IsAdminGroupMember(int processId)
    {
    IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
    var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
    if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
    var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
    if (haveToken)
    {
    haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
    WinApi.CloseHandle(hPriToken);
    }
    if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
    if (haveToken)
    {
    uint cbSid = 0;
    bool isMember = false;
    WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
    IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
    var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
    succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
    Marshal.FreeCoTaskMem(pSid);
    WinApi.CloseHandle(hImpToken);
    return succeed && isMember;
    }
    return false;
    }


    [STAThread]static void Main(/*string args*/)
    {

    bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
    Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
    }





    share|improve this answer
























    • must be not ProcessAccessFlags.QueryInformation but ask only for PROCESS_QUERY_LIMITED_INFORMATION (not admin process can not open admin with ProcessAccessFlags.QueryInformation (i guess that this is equal to PROCESS_QUERY_INFORMATION. also we can call DuplicateToken without Ex here and if want be correct check that first call to CreateWellKnownSid fail with ERROR_INSUFFICIENT_BUFFER

      – RbMm
      Nov 24 '18 at 17:35











    • @RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.

      – Anders
      Nov 24 '18 at 17:46











    • It tries limited information first, then it tries the old one for XP - sorry - not note this in your code. CreateWellKnownSid - yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented

      – RbMm
      Nov 24 '18 at 17:54













    • about access - i be use dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation and call OpenProcess only once

      – RbMm
      Nov 24 '18 at 18:02








    • 1





      Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.

      – Anders
      Nov 24 '18 at 18:43


















    4














    You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); ), that makes no sense.



    You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership.



    You also need to close these handles with CloseHandle.



    using System;
    using System.Runtime.InteropServices;
    ...
    public class WinApi
    {
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_QUERY = 0x00000008;
    public const int SecurityImpersonation = 2;
    public const int TokenImpersonation = 2;

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int GetCurrentProcessId();
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int CloseHandle(IntPtr h);
    }

    public enum ProcessAccessFlags : uint
    {
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x1000
    }

    public enum WELL_KNOWN_SID_TYPE
    {
    WinBuiltinAdministratorsSid = 26
    }

    private static bool IsAdminGroupMember(int processId)
    {
    IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
    var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
    if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
    var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
    if (haveToken)
    {
    haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
    WinApi.CloseHandle(hPriToken);
    }
    if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
    if (haveToken)
    {
    uint cbSid = 0;
    bool isMember = false;
    WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
    IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
    var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
    succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
    Marshal.FreeCoTaskMem(pSid);
    WinApi.CloseHandle(hImpToken);
    return succeed && isMember;
    }
    return false;
    }


    [STAThread]static void Main(/*string args*/)
    {

    bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
    Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
    }





    share|improve this answer
























    • must be not ProcessAccessFlags.QueryInformation but ask only for PROCESS_QUERY_LIMITED_INFORMATION (not admin process can not open admin with ProcessAccessFlags.QueryInformation (i guess that this is equal to PROCESS_QUERY_INFORMATION. also we can call DuplicateToken without Ex here and if want be correct check that first call to CreateWellKnownSid fail with ERROR_INSUFFICIENT_BUFFER

      – RbMm
      Nov 24 '18 at 17:35











    • @RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.

      – Anders
      Nov 24 '18 at 17:46











    • It tries limited information first, then it tries the old one for XP - sorry - not note this in your code. CreateWellKnownSid - yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented

      – RbMm
      Nov 24 '18 at 17:54













    • about access - i be use dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation and call OpenProcess only once

      – RbMm
      Nov 24 '18 at 18:02








    • 1





      Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.

      – Anders
      Nov 24 '18 at 18:43
















    4












    4








    4







    You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); ), that makes no sense.



    You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership.



    You also need to close these handles with CloseHandle.



    using System;
    using System.Runtime.InteropServices;
    ...
    public class WinApi
    {
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_QUERY = 0x00000008;
    public const int SecurityImpersonation = 2;
    public const int TokenImpersonation = 2;

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int GetCurrentProcessId();
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int CloseHandle(IntPtr h);
    }

    public enum ProcessAccessFlags : uint
    {
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x1000
    }

    public enum WELL_KNOWN_SID_TYPE
    {
    WinBuiltinAdministratorsSid = 26
    }

    private static bool IsAdminGroupMember(int processId)
    {
    IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
    var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
    if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
    var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
    if (haveToken)
    {
    haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
    WinApi.CloseHandle(hPriToken);
    }
    if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
    if (haveToken)
    {
    uint cbSid = 0;
    bool isMember = false;
    WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
    IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
    var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
    succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
    Marshal.FreeCoTaskMem(pSid);
    WinApi.CloseHandle(hImpToken);
    return succeed && isMember;
    }
    return false;
    }


    [STAThread]static void Main(/*string args*/)
    {

    bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
    Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
    }





    share|improve this answer













    You cannot add handles together (new IntPtr(hProcess.ToInt64() + hToken.ToInt64()); ), that makes no sense.



    You need the process handle to get the process token handle, then pass the token handle to CheckTokenMembership.



    You also need to close these handles with CloseHandle.



    using System;
    using System.Runtime.InteropServices;
    ...
    public class WinApi
    {
    public const int TOKEN_DUPLICATE = 0x0002;
    public const int TOKEN_QUERY = 0x00000008;
    public const int SecurityImpersonation = 2;
    public const int TokenImpersonation = 2;

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool DuplicateTokenEx(IntPtr hTok, UInt32 DesiredAccess, IntPtr SecAttPtr, int ImpLvl, int TokType, out IntPtr TokenHandle);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern IntPtr OpenProcess(ProcessAccessFlags processAccess, bool bInheritHandle, int processId);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CreateWellKnownSid(WELL_KNOWN_SID_TYPE WellKnownSidType, IntPtr DomainSid, IntPtr pSid, ref uint cbSid);

    [DllImport("advapi32.dll", SetLastError = true)] [return: MarshalAs(UnmanagedType.Bool)]
    public static extern bool CheckTokenMembership(IntPtr TokenHandle, IntPtr SidToCheck, out bool IsMember);

    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int GetCurrentProcessId();
    [DllImport("kernel32.dll", SetLastError = true)]
    public static extern int CloseHandle(IntPtr h);
    }

    public enum ProcessAccessFlags : uint
    {
    QueryInformation = 0x00000400,
    QueryLimitedInformation = 0x1000
    }

    public enum WELL_KNOWN_SID_TYPE
    {
    WinBuiltinAdministratorsSid = 26
    }

    private static bool IsAdminGroupMember(int processId)
    {
    IntPtr hPriToken = IntPtr.Zero, hImpToken = IntPtr.Zero;
    var hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryLimitedInformation, false, processId);
    if (hProcess == IntPtr.Zero) hProcess = WinApi.OpenProcess(ProcessAccessFlags.QueryInformation, false, processId); // < Vista
    var haveToken = WinApi.OpenProcessToken(hProcess, WinApi.TOKEN_DUPLICATE, out hPriToken);
    if (haveToken)
    {
    haveToken = WinApi.DuplicateTokenEx(hPriToken, WinApi.TOKEN_QUERY, IntPtr.Zero, WinApi.SecurityImpersonation, WinApi.TokenImpersonation, out hImpToken);
    WinApi.CloseHandle(hPriToken);
    }
    if (hProcess != IntPtr.Zero) WinApi.CloseHandle(hProcess);
    if (haveToken)
    {
    uint cbSid = 0;
    bool isMember = false;
    WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, IntPtr.Zero, ref cbSid);
    IntPtr pSid = Marshal.AllocCoTaskMem(Convert.ToInt32(cbSid));
    var succeed = pSid != IntPtr.Zero && WinApi.CreateWellKnownSid(WELL_KNOWN_SID_TYPE.WinBuiltinAdministratorsSid, IntPtr.Zero, pSid, ref cbSid);
    succeed = succeed && WinApi.CheckTokenMembership(hImpToken, pSid, out isMember);
    Marshal.FreeCoTaskMem(pSid);
    WinApi.CloseHandle(hImpToken);
    return succeed && isMember;
    }
    return false;
    }


    [STAThread]static void Main(/*string args*/)
    {

    bool admin = IsAdminGroupMember(WinApi.GetCurrentProcessId());
    Console.WriteLine(string.Format("IsAdminGroupMember={0}", admin));
    }






    share|improve this answer












    share|improve this answer



    share|improve this answer










    answered Nov 24 '18 at 15:59









    AndersAnders

    71.2k1076129




    71.2k1076129













    • must be not ProcessAccessFlags.QueryInformation but ask only for PROCESS_QUERY_LIMITED_INFORMATION (not admin process can not open admin with ProcessAccessFlags.QueryInformation (i guess that this is equal to PROCESS_QUERY_INFORMATION. also we can call DuplicateToken without Ex here and if want be correct check that first call to CreateWellKnownSid fail with ERROR_INSUFFICIENT_BUFFER

      – RbMm
      Nov 24 '18 at 17:35











    • @RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.

      – Anders
      Nov 24 '18 at 17:46











    • It tries limited information first, then it tries the old one for XP - sorry - not note this in your code. CreateWellKnownSid - yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented

      – RbMm
      Nov 24 '18 at 17:54













    • about access - i be use dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation and call OpenProcess only once

      – RbMm
      Nov 24 '18 at 18:02








    • 1





      Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.

      – Anders
      Nov 24 '18 at 18:43





















    • must be not ProcessAccessFlags.QueryInformation but ask only for PROCESS_QUERY_LIMITED_INFORMATION (not admin process can not open admin with ProcessAccessFlags.QueryInformation (i guess that this is equal to PROCESS_QUERY_INFORMATION. also we can call DuplicateToken without Ex here and if want be correct check that first call to CreateWellKnownSid fail with ERROR_INSUFFICIENT_BUFFER

      – RbMm
      Nov 24 '18 at 17:35











    • @RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.

      – Anders
      Nov 24 '18 at 17:46











    • It tries limited information first, then it tries the old one for XP - sorry - not note this in your code. CreateWellKnownSid - yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented

      – RbMm
      Nov 24 '18 at 17:54













    • about access - i be use dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation and call OpenProcess only once

      – RbMm
      Nov 24 '18 at 18:02








    • 1





      Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.

      – Anders
      Nov 24 '18 at 18:43



















    must be not ProcessAccessFlags.QueryInformation but ask only for PROCESS_QUERY_LIMITED_INFORMATION (not admin process can not open admin with ProcessAccessFlags.QueryInformation (i guess that this is equal to PROCESS_QUERY_INFORMATION. also we can call DuplicateToken without Ex here and if want be correct check that first call to CreateWellKnownSid fail with ERROR_INSUFFICIENT_BUFFER

    – RbMm
    Nov 24 '18 at 17:35





    must be not ProcessAccessFlags.QueryInformation but ask only for PROCESS_QUERY_LIMITED_INFORMATION (not admin process can not open admin with ProcessAccessFlags.QueryInformation (i guess that this is equal to PROCESS_QUERY_INFORMATION. also we can call DuplicateToken without Ex here and if want be correct check that first call to CreateWellKnownSid fail with ERROR_INSUFFICIENT_BUFFER

    – RbMm
    Nov 24 '18 at 17:35













    @RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.

    – Anders
    Nov 24 '18 at 17:46





    @RbMM: It tries limited information first, then it tries the old one for XP. Technically, the documentation does not say that CreateWellKnownSid fails with a specific error. Either way, if cbSid is somehow incorrect then the memory allocation will fail or the next call to CreateWellKnownSid will fail, either way, the code is safe.

    – Anders
    Nov 24 '18 at 17:46













    It tries limited information first, then it tries the old one for XP - sorry - not note this in your code. CreateWellKnownSid - yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented

    – RbMm
    Nov 24 '18 at 17:54







    It tries limited information first, then it tries the old one for XP - sorry - not note this in your code. CreateWellKnownSid - yes, which error returned in case we pass 0 pointer and 0 size not documented, but from another side not check error of api call and just try allocate cbSid also wrong. may be sid type unknown ? more correct anyway check for this error, even if not explicit documented

    – RbMm
    Nov 24 '18 at 17:54















    about access - i be use dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation and call OpenProcess only once

    – RbMm
    Nov 24 '18 at 18:02







    about access - i be use dwAccess = ver < 6.0 ? QueryInformation : QueryLimitedInformation and call OpenProcess only once

    – RbMm
    Nov 24 '18 at 18:02






    1




    1





    Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.

    – Anders
    Nov 24 '18 at 18:43







    Microsoft says you are not suppose to do version checks. Anyway, only on < Vista will it call OpenProcess twice, not a big deal. Just allocating cbSid is fine, if it is a very large size then memory allocation might fail but that is fine if the SID was not well known. In this case we hardcode the well known sid so we know it will work.

    – Anders
    Nov 24 '18 at 18:43















    1














    I have created Process.Extensions.dll extension using solution offered by Anders



    using System;
    using ProcessExtensions;
    using System.Diagnostics;
    static void Main(string args)
    {
    bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
    Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
    }


    https://github.com/IamhereTeam/Process.Extensions.git



    Process.Extensions.dll






    share|improve this answer






























      1














      I have created Process.Extensions.dll extension using solution offered by Anders



      using System;
      using ProcessExtensions;
      using System.Diagnostics;
      static void Main(string args)
      {
      bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
      Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
      }


      https://github.com/IamhereTeam/Process.Extensions.git



      Process.Extensions.dll






      share|improve this answer




























        1












        1








        1







        I have created Process.Extensions.dll extension using solution offered by Anders



        using System;
        using ProcessExtensions;
        using System.Diagnostics;
        static void Main(string args)
        {
        bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
        Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
        }


        https://github.com/IamhereTeam/Process.Extensions.git



        Process.Extensions.dll






        share|improve this answer















        I have created Process.Extensions.dll extension using solution offered by Anders



        using System;
        using ProcessExtensions;
        using System.Diagnostics;
        static void Main(string args)
        {
        bool isAdminGroupMember = Process.GetCurrentProcess().IsAdminGroupMember();
        Console.WriteLine(string.Format("IsAdminGroupMember={0}", isAdminGroupMember));
        }


        https://github.com/IamhereTeam/Process.Extensions.git



        Process.Extensions.dll







        share|improve this answer














        share|improve this answer



        share|improve this answer








        edited Nov 24 '18 at 17:44

























        answered Nov 24 '18 at 17:30









        Grigor YeghiazaryanGrigor Yeghiazaryan

        12816




        12816






























            draft saved

            draft discarded




















































            Thanks for contributing an answer to Stack Overflow!


            • Please be sure to answer the question. Provide details and share your research!

            But avoid



            • Asking for help, clarification, or responding to other answers.

            • Making statements based on opinion; back them up with references or personal experience.


            To learn more, see our tips on writing great answers.




            draft saved


            draft discarded














            StackExchange.ready(
            function () {
            StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53459123%2fcheck-if-another-process-has-admin-privileges%23new-answer', 'question_page');
            }
            );

            Post as a guest















            Required, but never shown





















































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown

































            Required, but never shown














            Required, but never shown












            Required, but never shown







            Required, but never shown







            這個網誌中的熱門文章

            Tangent Lines Diagram Along Smooth Curve

            Yusuf al-Mu'taman ibn Hud

            Zucchini