ChatGPT解决这个技术问题 Extra ChatGPT

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

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

在模拟的上下文中,用户名可能与登录的用户会话用户名不同(例如托管代码中的 runas 或 .Net 模拟),请参阅下面的其他人的评论

M
MGot90

选项 A)

string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;

返回:网络名称\用户名

获取用户的 Windows 登录名。

详细信息:https://docs.microsoft.com/en-us/dotnet/api/system.security.principal.windowsidentity

选项 B)

string userName = Environment.UserName

返回:用户名

获取与当前线程关联的人员的用户名。

详细信息:https://docs.microsoft.com/en-us/dotnet/api/system.environment.username


这与 Environment.UserName 有何不同?
@SimonGillbee,这是错误的,Environment.UserName 将返回“RunAs”用户。
验证.... MessageBox.Show(Environment.UserName); 将其放入您的 window_loaded 事件中,并使用 RunAs 运行它...。
这将返回 Domain\Username。如何获取与用户名关联的名称?
P
Peter Mortensen

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

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];
T
Tim Cooper

尝试属性:Environment.UserName


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

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

Environment.UserName Property

在同一页上它说:

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

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

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


P
Peter Mortensen

我完全支持其他答案,但我想强调另一种方法,它说

String UserName = Request.LogonUserIdentity.Name;

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

这不同于:

String UserName = Environment.UserName;

其中显示格式为:用户名

最后:

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

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


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

利用:

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

这将是登录名。


A
AakashM
String myUserName = Environment.UserName

这会给你输出 - your_user_name


B
B Bhatnagar

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

这是款待:

System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName

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


j
jay_t55

您可能还想尝试使用:

Environment.UserName;

像这样...:

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

希望这对您有所帮助。


D
Daniel E.

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

DefaultAppPool
IIS APPPOOL
IIS APPPOOL\DefaultAppPool

我最终使用

string vUserName = User.Identity.Name;

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


出色的。我也只收到了应用程序池标识。但是你的代码解决了我的问题。太感谢了。
听起来您想要发出请求的用户的用户名,我猜是 MVC 或 Web API 控制器。这与进程正在运行的用户名不同
@BenAaronson这个问题没有说明什么用户名正在运行进程。我需要当前登录的域用户名,然后搜索将我带到此页面,此代码最终为我提供了所需的内容。
R
Remy

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


谢谢分享,另见:System.Windows.Forms.SystemInformation.UserDomainName
F
FlashTrev

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

我在登录用户之后,如下所示:

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

这是我写的一个小函数来尝试它们。我的结果在每一行之后的评论中。

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

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

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


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

尝试这个

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

现在看起来好多了


感谢这个例子。请注意,这与上述答案不同,但正是我想要的。即使进程被提升并且现在以管理员名称运行,此代码也会返回登录的用户。我的 Setup.exe 需要这个。如果我在非用户帐户上运行 Setup.exe,Windows 安装程序会要求输入管理员帐户的密码。然后安装程序以管理员的用户名运行。 'Environment.UserName' 和 'System.Windows.Forms.SystemInformation.UserName' 以及 'System.Security.Principal.WindowsIdentity.GetCurrent().Name' 返回管理员用户,但不是这个。
请注意,如果没有登录用户,此代码将产生异常
S
Shaun Wilson

这是代码(但不是在 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# 中的答案
O
Oskar Berggren

对于要分发给多个用户的 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;
        }
    }
}

P
Peter Mortensen

获取当前的 Windows 用户名:

using System;

class Sample
{
    public static void Main()
    {
        Console.WriteLine();

        //  <-- Keep this information secure! -->
        Console.WriteLine("UserName: {0}", Environment.UserName);
    }
}

我的网站正在使用 IIS,但是当我从网络中的另一台计算机访问该页面时,我一直看到“网络服务”作为用户名。我尝试了所有不同的选项,但它没有给我正在查看页面的登录用户。任何想法?
D
Doreen

如果对其他人有帮助,当我将应用程序从 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 个字符的字符串引起的,这没什么做这个问题,然后只提到之前在其他答案中已经多次提到的解决方案。这个答案只是噪音,应该删除
A
Alonzzo2

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

就我而言,我想在从其他用户运行我的应用程序时获取登录的用户名,例如当 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;

编辑:根据评论请求,这是我获取会话 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 根据您的要求编辑了我的答案