Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/282.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# 如何确定普通用户是否正在使用提升的权限_C#_Uac_Admin Rights - Fatal编程技术网

C# 如何确定普通用户是否正在使用提升的权限

C# 如何确定普通用户是否正在使用提升的权限,c#,uac,admin-rights,C#,Uac,Admin Rights,我正在尝试使用以下代码确定我的程序是由具有管理员权限的管理员启动的,还是由具有管理员权限的普通用户启动的: private void Form1_Load(object sender, EventArgs e) { WindowsIdentity identity = WindowsIdentity.GetCurrent(); WindowsPrincipal principal = new WindowsPrincipal(identity);

我正在尝试使用以下代码确定我的程序是由具有管理员权限的管理员启动的,还是由具有管理员权限的普通用户启动的:

   private void Form1_Load(object sender, EventArgs e)
    {
      WindowsIdentity identity = WindowsIdentity.GetCurrent();
      WindowsPrincipal principal = new WindowsPrincipal(identity);
      bool isAdmin = principal.IsInRole(WindowsBuiltInRole.Administrator);

      if (isAdmin)
      {
          ini();
          MessageBox.Show("The user is an admin with admin rights");
      }
      else
      {
          MessageBox.Show("Error The user is a normal user with admin rights", MessageBoxButtons.OK, MessageBoxIcon.Exclamation);
          Application.Exit();
      }

    }
但是,当我使用具有管理员权限的普通用户帐户测试此代码时,它失败了,告诉我该用户是具有管理员权限的管理员

我使用的是.Net 3.5,代码需要与Windows Vista及更高版本兼容

有谁能给我一些解决这个问题的办法吗?谢谢你


为了进一步澄清一下,另一种看待这个问题的方法是:我如何确定我的程序是否在标准用户帐户上下文中运行,而该程序是由管理员使用管理员权限运行的。

mmm您需要知道的是,连接到该计算机的用户是否具有管理员权限,但该用户是域控件的一部分?活动目录?不是内置的吗?请澄清,看看这篇文章,还有更多的变量需要考虑,例如操作系统。您正在使用哪个版本的Microsoft Window?请记住,用户访问控制UAC是在更高版本中引入的,这可能会影响代码。另一个巨大的影响因素将是通过Active Directory管理的域策略

为了避免这些限制,我将采取以下措施:

private static bool IsElevated()
{
     var user = WindowsIdentity.GetCurrent();
     var role = WindowsPrincipal(user);
     if(Environment.OSVersion.Platform == PlatformID.Win32NT || Environment.OSVersion.Version.Major > 6)
           if(user != null)
                if(role.IsInRole(WindowsBuiltInRole.Administrator))
                     return true;

     return false;
}
这是一个快速的重新创建,但您需要测试代码以确保它正确地查询操作系统和用户。

我解决了它

解释

我意识到我需要的是会话ID,环境以某种方式获取登录用户名 上下文的所有者

获取会话Id非常容易:

int session=System.Diagnostics.Process.GetCurrentProcess.SessionId

此时,我的目标是将用户名链接到此会话,然后我发现

现在,有了这个用户名,我想检查这个用户名是否属于 添加到管理员组。我错了。我发现的最简单的方法是使用wmi和pinvoke

主要问题是,为了进行查询,我必须知道当前操作系统中管理员组的名称,这取决于语言

解决办法是:

我调整了代码,把所有的部分放在一起,就是这样

总之,我找到了sessionid,找到了链接到会话的用户名,找到了OS Administrators组名,并执行了一些Wmi查询以检查该用户是否是管理员

这个解决方案对我来说很好,但我必须说它运行缓慢

如果有人能改进这段代码,或者它对其他人有用,我就把它放在这里了

只需记住添加对系统的引用;我使用了Visual Studio C Express 2010。该项目是一个Windows窗体应用程序

快乐编码

//Make sure to add a reference to System.Management; 


using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Management;
using System.Security.Principal;
using System.Collections;
using System.Runtime.InteropServices;



namespace RealUSer
{
    public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            //Getting the session id
            int session = System.Diagnostics.Process.GetCurrentProcess().SessionId;
            //Getting the username related to the session id 
            string user = GetUsernameBySessionId(session, false);
            try
            {
                //Cheching if the user belongs to the local admin group using wmi
                if (CheckAdminRights(user))
                {
                    MessageBox.Show("The logged in User "+user+" is an Admin");
                }
                else
                {
                    MessageBox.Show("The logged in User " + user + " is not an Admin");
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex.Message);

            }

        }
        /// <summary>
        /// This method checks if the context user, belongs to the local administrators group
        /// </summary>
        /// <param name="username"></param>
        /// <returns></returns>

        public  bool CheckAdminRights(string username)
        {
            bool result = false;
            List<string> admins = new List<string>();
            //SelectQuery query = new SelectQuery("Select AccountType from Win32_UserAccount where Name=\"" + username + "\"");
            SelectQuery query = new SelectQuery("SELECT * FROM win32_group WHERE Name=\"" + getAdministratorGroupName() + "\"");
            ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
            ManagementObjectCollection OC = searcher.Get();
            IEnumerator enumerator = OC.GetEnumerator();
            enumerator.MoveNext();
            ManagementObject O = (ManagementObject)enumerator.Current;
            ManagementObjectCollection adminusers = O.GetRelated("Win32_UserAccount");
            foreach (ManagementObject envVar in adminusers)
            {
                admins.Add(envVar["Name"].ToString());
                //Console.WriteLine("Username : {0}", envVar["Name"]);
                //foreach (PropertyData pd in envVar.Properties)
                //    Console.WriteLine(string.Format("  {0,20}: {1}", pd.Name, pd.Value));
            }
            if (admins.Contains(username))
                result = true;
            return result;
        }
        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///This code will find the administrators group name, independent of the OS language using the LookupAccountSid function with the BUILTIN\Administrators sid

        #region


        const int NO_ERROR = 0;
        const int ERROR_INSUFFICIENT_BUFFER = 122;

        enum SID_NAME_USE
        {
            SidTypeUser = 1,
            SidTypeGroup,
            SidTypeDomain,
            SidTypeAlias,
            SidTypeWellKnownGroup,
            SidTypeDeletedAccount,
            SidTypeInvalid,
            SidTypeUnknown,
            SidTypeComputer
        }

        [DllImport("advapi32.dll", CharSet = CharSet.Auto, SetLastError = true)]
        static extern bool LookupAccountSid(
          string lpSystemName,
          [MarshalAs(UnmanagedType.LPArray)] byte[] Sid,
          StringBuilder lpName,
          ref uint cchName,
          StringBuilder ReferencedDomainName,
          ref uint cchReferencedDomainName,
          out SID_NAME_USE peUse);

        public  string getAdministratorGroupName()
        {
            String result = "";
            StringBuilder name = new StringBuilder();
            uint cchName = (uint)name.Capacity;
            StringBuilder referencedDomainName = new StringBuilder();
            uint cchReferencedDomainName = (uint)referencedDomainName.Capacity;
            SID_NAME_USE sidUse;
            // Sid for BUILTIN\Administrators
            byte[] Sid = new byte[] { 1, 2, 0, 0, 0, 0, 0, 5, 32, 0, 0, 0, 32, 2 };

            int err = NO_ERROR;
            if (!LookupAccountSid(null, Sid, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))
            {
                err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                if (err == ERROR_INSUFFICIENT_BUFFER)
                {
                    name.EnsureCapacity((int)cchName);
                    referencedDomainName.EnsureCapacity((int)cchReferencedDomainName);
                    err = NO_ERROR;
                    if (!LookupAccountSid(null, Sid, name, ref cchName, referencedDomainName, ref cchReferencedDomainName, out sidUse))
                        err = System.Runtime.InteropServices.Marshal.GetLastWin32Error();
                }
            }
            if (err == 0)
            {
                result = name.ToString();
            }

            return result;
        }

        #endregion


        ///////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

        private void Form1_Load(object sender, EventArgs e)
        {

        }



        ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
        ///This code will retrieve user name given the session id

        #region
        [DllImport("Wtsapi32.dll")]
        private static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTS_INFO_CLASS wtsInfoClass, out System.IntPtr ppBuffer, out int pBytesReturned);
        [DllImport("Wtsapi32.dll")]
        private static extern void WTSFreeMemory(IntPtr pointer);

        public static string GetUsernameBySessionId(int sessionId, bool prependDomain)
        {
            IntPtr buffer;
            int strLen;
            string username = "SYSTEM";
            if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSUserName, out buffer, out strLen) && strLen > 1)
            {
                username = Marshal.PtrToStringAnsi(buffer);
                WTSFreeMemory(buffer);
                if (prependDomain)
                {
                    if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WTS_INFO_CLASS.WTSDomainName, out buffer, out strLen) && strLen > 1)
                    {
                        username = Marshal.PtrToStringAnsi(buffer) + "\\" + username;
                        WTSFreeMemory(buffer);
                    }
                }
            }
            return username;
        }
        public enum WTS_INFO_CLASS
        {
            WTSInitialProgram,
            WTSApplicationName,
            WTSWorkingDirectory,
            WTSOEMId,
            WTSSessionId,
            WTSUserName,
            WTSWinStationName,
            WTSDomainName,
            WTSConnectState,
            WTSClientBuildNumber,
            WTSClientName,
            WTSClientDirectory,
            WTSClientProductId,
            WTSClientHardwareId,
            WTSClientAddress,
            WTSClientDisplay,
            WTSClientProtocolType
        }
        #endregion
    }
}

您对具有管理员权限的普通用户和管理员的定义是什么?对我来说,它们似乎是同一概念的两个不同术语。对我来说,我所说的普通用户是一个标准用户,不属于管理员组,也没有任何权力。例如,普通用户需要给管理员密码才能安装程序。管理员是属于管理员组的超级用户,在系统中拥有许多权限,例如,当他想要安装程序时,只需单击“允许UAC消息”。我已经尝试了你的代码,它对我有效。我不知道,也许像RobDev说的那样,你在特定用户的角色/权限方面遗漏了一些东西。啊,好吧,但在这种情况下,正常用户不是运行你程序的用户。您的程序正在以普通用户允许其作为的管理员帐户运行。我会称之为没有管理员权限的普通用户,不管它值多少钱。@hvd好吧,我明白,那么我真正需要知道的是:上下文。我如何确定我的程序是否在标准用户帐户上下文中运行,并由管理员授予管理员权限。谢谢您的回答!为了澄清,我不需要处理域控件或active directory。我只考虑单机版。有疑问的是,使用上述代码,您是否仅针对登录用户权限或针对@ccarmona1981创建的所有用户获得了正确的admin结果访问权限