【问题标题】:How do I get the current username in .NET using C#?如何使用 C# 在 .NET 中获取当前用户名?
【发布时间】:2009-08-06 17:40:27
【问题描述】:

如何使用 C# 在 .NET 中获取当前用户名?

【问题讨论】:

  • 在模拟的上下文中,用户名可以不同于登录的用户会话用户名(例如 runas 或托管代码中的 .Net 模拟),请参见下面的其他 cmets

标签: c# .net


【解决方案1】:
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

【讨论】:

  • 这和Environment.UserName有什么不同?
  • @SimonGillbee,这是错误的,Environment.UserName 将返回“RunAs”用户。
  • 验证.... MessageBox.Show(Environment.UserName); 将其放入您的window_loaded 事件中,并使用 RunAs 运行它....
  • 这将返回 Domain\Username。如何获取与用户名关联的名称?
【解决方案2】:

如果您在用户网络中,则用户名将不同:

Environment.UserName
- Will Display format : 'Username'

而不是

System.Security.Principal.WindowsIdentity.GetCurrent().Name
- Will Display format : 'NetworkName\Username'

选择你想要的格式。

【讨论】:

  • 您可以使用Environment.UserDomainName + "\\" + Environment.UserName 获得与System.Security.Principal.WindowsIdentity.GetCurrent().Name 看似相同的结果。现在,你问有什么区别......我不确定。
  • 我需要让用户运行应用程序而不是让谁登录(Environment.UserName 不是我想要的),所以我做了以下操作来剥离域:System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split( '\\' ).Last();
  • 在调用Last()之前需要在Split之后添加ToArray()
  • @codenamezero 不需要ToArray()。不过你需要using System.Linq;
  • 或者不使用 Linq:System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split( '\\' )[1];.
【解决方案3】:

试试属性:Environment.UserName

【讨论】:

  • 或者,string userName = Environment.UserName;
  • 警告:就像接受答案的 cmets 中提到的 Simon Gillbee 一样,Environment.UsernName 给出了登录的帐户名,但WindowsIdentity.GetCurrent().Name 正在返回应用程序运行的帐户名.
  • @leo:警告:该信息显然也不正确,请参阅Bolu's reply。 :-)
  • 不要在 ASP.NET 中使用它。 docs.microsoft.com 说:“如果 ASP.NET 应用程序在开发环境中运行,则 UserName 属性返回当前用户的名称。在已发布的 ASP.NET 应用程序中,此属性返回应用程序池帐户的名称(例如默认应用程序池)。”
【解决方案4】:

Environment.UserName 的文档似乎有点矛盾:

Environment.UserName Property

在同一页上写着:

获取当前登录到 Windows 操作系统的人的用户名。

显示启动当前线程的人的用户名

如果您使用 RunAs 测试 Environment.UserName,它将为您提供 RunAs 用户帐户名称,而不是最初登录到 Windows 的用户。

【讨论】:

    【解决方案5】:

    我完全赞同其他答案,但我想强调另一种方法

    String UserName = Request.LogonUserIdentity.Name;
    

    上述方法返回的用户名格式为:DomainName\UserName。例如,EUROPE\UserName

    不同于:

    String UserName = Environment.UserName;
    

    以以下格式显示:用户名

    最后:

    String UserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
    

    给出:NT AUTHORITY\IUSR(在 IIS 服务器上运行应用程序时)和 DomainName\UserName(在本地服务器上运行应用程序时)。

    【讨论】:

    • 使用“请求”需要什么命名空间?
    • @TK-421 Request 仅适用于 Web 应用程序。这是System.Web.HttpRequest的一个实例@
    • @GerardoGrignoli - 感谢您的评论,是的,请求仅在您使用网络应用程序时才有效。
    • 任何只是向您抛出类型名称而不提及命名空间(更不用说程序集的全名)的答案都应该被否决。不幸的是,如果我们要这样做,我们将不得不对所有 C# 答案的 99% 投反对票。哦,人类。
    【解决方案6】:

    用途:

    System.Security.Principal.WindowsIdentity.GetCurrent().Name
    

    这将是登录名。

    【讨论】:

      【解决方案7】:
      String myUserName = Environment.UserName
      

      这将为您提供输出 - your_user_name

      【讨论】:

        【解决方案8】:

        以防万一有人在寻找用户显示名称,而不是用户名,比如我。

        这是款待:

        System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName

        在您的项目中添加对System.DirectoryServices.AccountManagement 的引用。

        【讨论】:

          【解决方案9】:

          您可能还想尝试使用:

          Environment.UserName;
          

          像这样...:

          string j = "Your WindowsXP Account Name is: " + Environment.UserName;
          

          希望这对您有所帮助。

          【讨论】:

            【解决方案10】:

            我从现有答案中尝试了几种组合,但他们给了我

            DefaultAppPool
            IIS APPPOOL
            IIS APPPOOL\DefaultAppPool
            

            我最终使用了

            string vUserName = User.Identity.Name;
            

            它只给了我实际用户的域用户名。

            【讨论】:

            • 优秀。我也只收到了应用程序池标识。但是你的代码解决了我的问题。非常感谢。
            • 听起来您想要发出请求的用户的用户名,我猜是 MVC 或 Web API 控制器。这与进程在其下运行的用户名不同
            • @BenAaronson 这个问题没有说明什么用户名正在运行进程。我需要当前登录的域用户名,搜索将我带到了这个页面,这段代码最终给了我我需要的东西。
            【解决方案11】:

            对实际登录的用户使用System.Windows.Forms.SystemInformation.UserName,因为Environment.UserName仍然返回当前进程正在使用的帐户。

            【讨论】:

            • 感谢分享,另见:System.Windows.Forms.SystemInformation.UserDomainName
            【解决方案12】:

            我已经尝试了所有以前的答案并在 MSDN 上找到了答案,但这些都不适合我。请参阅“UserName4”以获取适合我的正确用户名。

            我在关注登录用户,如下所示:

            <asp:LoginName ID="LoginName1" runat="server" />
            

            这是我写的一个小函数来尝试所有这些。我的结果在每行之后的 cmets 中。

            protected string GetLoggedInUsername()
            {
                string UserName = System.Security.Principal.WindowsIdentity.GetCurrent().Name; // Gives NT AUTHORITY\SYSTEM
                String UserName2 = Request.LogonUserIdentity.Name; // Gives NT AUTHORITY\SYSTEM
                String UserName3 = Environment.UserName; // Gives SYSTEM
                string UserName4 = HttpContext.Current.User.Identity.Name; // Gives actual user logged on (as seen in <ASP:Login />)
                string UserName5 = System.Windows.Forms.SystemInformation.UserName; // Gives SYSTEM
                return UserName4;
            }
            

            调用该函数以return的方式返回登录的用户名。

            更新:我想指出,在我的本地服务器实例上运行此代码显示 Username4 返回“”(一个空字符串),但 UserName3 和 UserName5 返回登录的用户。只是需要提防。

            【讨论】:

            • 我的网站正在使用 IIS,但是当我从网络中的另一台计算机访问该页面时,我一直看到“网络服务”作为用户名。我尝试了所有不同的选项,但它没有给我正在查看页面的登录用户。有什么想法吗?
            • 注意:不清楚,但上面的示例适用于在 IIS 中运行的 Web 应用程序的上下文,其中有几个将显示执行 ASP.Net 的服务器 windows 帐户的名称应用程序池。如果作为交互式程序或windows服务运行,来自HttpContext的那个将不可用,而其他的一个应该用于查找进程执行的帐户。
            【解决方案13】:

            试试这个

            ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
            ManagementObjectCollection collection = searcher.Get();
            string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
            

            现在看起来好多了

            【讨论】:

              【解决方案14】:

              这是代码(但不是 C# 代码):

              Private m_CurUser As String
              
              Public ReadOnly Property CurrentUser As String
                  Get
                      If String.IsNullOrEmpty(m_CurUser) Then
                          Dim who As System.Security.Principal.IIdentity = System.Security.Principal.WindowsIdentity.GetCurrent()
              
                          If who Is Nothing Then
                              m_CurUser = Environment.UserDomainName & "\" & Environment.UserName
                          Else
                              m_CurUser = who.Name
                          End If
                      End If
                      Return m_CurUser
                  End Get
              End Property
              

              这里是代码(现在也用 C#):

              private string m_CurUser;
              
              public string CurrentUser
              {
                  get
                  {
                      if(string.IsNullOrEmpty(m_CurUser))
                      {
                          var who = System.Security.Principal.WindowsIdentity.GetCurrent();
                          if (who == null)
                              m_CurUser = System.Environment.UserDomainName + @"\" + System.Environment.UserName;
                          else
                              m_CurUser = who.Name;
                      }
                      return m_CurUser;
                  }
              }
              

              【讨论】:

              • 假设是 C# 中的答案
              【解决方案15】:

              对于要分发给多个用户的 Windows 窗体应用程序,其中许多用户通过 vpn 登录,我尝试了几种方法,这些方法都适用于我的本地机器测试,但不适用于其他用户。我偶然发现了一篇我改编并工作的 Microsoft 文章。

              using System;
              using System.Security.Principal;
              
              namespace ManageExclusion
              {
                  public static class UserIdentity
              
                  {
                      // concept borrowed from 
                      // https://msdn.microsoft.com/en-us/library/system.security.principal.windowsidentity(v=vs.110).aspx
              
                      public static string GetUser()
                      {
                          IntPtr accountToken = WindowsIdentity.GetCurrent().Token;
                          WindowsIdentity windowsIdentity = new WindowsIdentity(accountToken);
                          return windowsIdentity.Name;
                      }
                  }
              }
              

              【讨论】:

                【解决方案16】:

                获取当前的 Windows 用户名:

                using System;
                
                class Sample
                {
                    public static void Main()
                    {
                        Console.WriteLine();
                
                        //  <-- Keep this information secure! -->
                        Console.WriteLine("UserName: {0}", Environment.UserName);
                    }
                }
                

                【讨论】:

                • 我的网站正在使用 IIS,但是当我从网络中的另一台计算机访问该页面时,我一直看到“网络服务”作为用户名。我尝试了所有不同的选项,但它没有给我正在查看页面的登录用户。有什么想法吗?
                【解决方案17】:

                如果对其他人有帮助,当我将应用程序从 c#.net 3.5 应用程序升级到 Visual Studio 2017 时,这行代码 User.Identity.Name.Substring(4); 抛出此错误“startIndex 不能大于字符串长度"(它之前没有退缩)。

                当我将其更改为 System.Security.Principal.WindowsIdentity.GetCurrent().Name 时很高兴,但是我最终使用 Environment.UserName; 来获取登录的 Windows 用户并且没有域部分。

                【讨论】:

                • 我已将其标记为“不是答案”,因为它开始谈论一个完全不相关的异常,这是由于您盲目地尝试 substring(4) 显然没有至少 4 的字符串其中的字符,与问题无关,然后只提到之前在其他答案中已经多次提到的解决方案。这个答案只是噪音,应该删除
                【解决方案18】:

                我在这里查看了大部分答案,但没有一个给我正确的用户名。

                在我的情况下,我想在从其他用户运行我的应用程序时获取登录的用户名,例如当 shift+右键单击文件并“以其他用户身份运行”时。

                我尝试的答案给了我“其他”用户名。

                这篇博文提供了一种获取登录用户名的方法,即使在我的场景中也可以使用:
                https://smbadiwe.github.io/post/track-activities-windows-service/

                它使用 Wtsapi

                编辑:博客文章中的基本代码,以防它消失,是

                将此代码添加到继承自 ServiceBase 的类中

                [DllImport("Wtsapi32.dll")]
                private static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WtsInfoClass wtsInfoClass, out IntPtr ppBuffer, out int pBytesReturned);
                [DllImport("Wtsapi32.dll")]
                private static extern void WTSFreeMemory(IntPtr pointer);
                 
                private enum WtsInfoClass
                {
                    WTSUserName = 5, 
                    WTSDomainName = 7,
                }
                 
                private static string GetUsername(int sessionId, bool prependDomain = true)
                {
                    IntPtr buffer;
                    int strLen;
                    string username = "SYSTEM";
                    if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSUserName, out buffer, out strLen) && strLen > 1)
                    {
                        username = Marshal.PtrToStringAnsi(buffer);
                        WTSFreeMemory(buffer);
                        if (prependDomain)
                        {
                            if (WTSQuerySessionInformation(IntPtr.Zero, sessionId, WtsInfoClass.WTSDomainName, out buffer, out strLen) && strLen > 1)
                            {
                                username = Marshal.PtrToStringAnsi(buffer) + "\\" + username;
                                WTSFreeMemory(buffer);
                            }
                        }
                    }
                    return username;
                }
                

                如果您还没有,请在类中添加一个构造函数;并将这一行添加到其中:

                CanHandleSessionChangeEvent = true;
                

                编辑: 根据 cmets 请求,以下是我获取会话 ID 的方式 - 这是活动控制台会话 ID:

                [DllImport("kernel32.dll")]
                private static extern uint WTSGetActiveConsoleSessionId();
                
                var activeSessionId = WTSGetActiveConsoleSessionId();
                if (activeSessionId == INVALID_SESSION_ID) //failed
                {
                    logger.WriteLog("No session attached to console!");    
                }
                

                【讨论】:

                • 始终将外部内容复制到您的答案中,而不仅仅是放置链接。如果链接死了,你的答案就没用了
                • 有趣的方法。但是,您如何获得会话 ID?
                • @Lopside 根据您的要求编辑了我的答案
                猜你喜欢
                • 2012-07-20
                • 2013-10-18
                • 2018-02-17
                • 2014-08-21
                • 1970-01-01
                • 2011-01-06
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多