Detect if another process is started as “Run as Administrator”

前端 未结 2 1603
萌比男神i
萌比男神i 2020-12-21 03:39

Our application needs to communicate with another program through a COM interface. The interface will not work if the other program is started with \"Run as Administrator\"

2条回答
  •  夕颜
    夕颜 (楼主)
    2020-12-21 04:19

    You can try something like this:

    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Runtime.InteropServices;
    using System.Diagnostics;
    using System.Security.Principal;
    using System.Reflection;
    
    namespace WindowsFormsApplication2
    {
    
        public class ProcessHelper
        {
            [DllImport("advapi32.dll", SetLastError = true)]
            private static extern bool OpenProcessToken(IntPtr ProcessHandle, UInt32 DesiredAccess, out IntPtr TokenHandle);
    
            [DllImport("kernel32.dll", SetLastError = true)]
            private static extern bool CloseHandle(IntPtr hObject);
    
            private const int STANDARD_RIGHTS_REQUIRED      = 0xF0000;
            private const int TOKEN_ASSIGN_PRIMARY           =0x1;
            private const int TOKEN_DUPLICATE                 = 0x2;
            private const int TOKEN_IMPERSONATE              = 0x4;
            private const int TOKEN_QUERY                     = 0x8;
            private const int TOKEN_QUERY_SOURCE             = 0x10;
            private const int TOKEN_ADJUST_GROUPS           = 0x40;
            private const int TOKEN_ADJUST_PRIVILEGES        = 0x20;
            private const int TOKEN_ADJUST_SESSIONID          = 0x100;
            private const int TOKEN_ADJUST_DEFAULT          = 0x80;
            private const int TOKEN_ALL_ACCESS = (STANDARD_RIGHTS_REQUIRED | TOKEN_ASSIGN_PRIMARY | TOKEN_DUPLICATE | TOKEN_IMPERSONATE | TOKEN_QUERY | TOKEN_QUERY_SOURCE | TOKEN_ADJUST_PRIVILEGES | TOKEN_ADJUST_GROUPS | TOKEN_ADJUST_SESSIONID | TOKEN_ADJUST_DEFAULT);
    
            public static bool IsProcessOwnerAdmin(string processName)
            {
                Process proc = Process.GetProcessesByName(processName)[0];
    
                IntPtr ph = IntPtr.Zero;
    
                OpenProcessToken(proc.Handle, TOKEN_ALL_ACCESS, out ph);
    
                WindowsIdentity iden = new WindowsIdentity(ph);
    
                bool result = false;
    
                foreach (IdentityReference role in iden.Groups)
                {
                    if (role.IsValidTargetType(typeof(SecurityIdentifier)))
                    {
                        SecurityIdentifier sid = role as SecurityIdentifier;
    
                        if (sid.IsWellKnown(WellKnownSidType.AccountAdministratorSid) || sid.IsWellKnown(WellKnownSidType.BuiltinAdministratorsSid))
                        {
                            result = true;
                            break;
                        }
                    }
                }
    
                CloseHandle(ph);
    
                return result;
            }
        }
    
        static class Program
        {
            [STAThread]
            static void Main()
            {
                bool isAdmin = ProcessHelper.IsProcessOwnerAdmin("outlook");
            }
        }
    }
    

    This could also be a good thing to have: Well-known security identifiers in Windows operating systems

    That should be a good start point :-)

提交回复
热议问题