【发布时间】:2009-08-06 17:40:27
【问题描述】:
如何使用 C# 在 .NET 中获取当前用户名?
【问题讨论】:
-
在模拟的上下文中,用户名可以不同于登录的用户会话用户名(例如 runas 或托管代码中的 .Net 模拟),请参见下面的其他 cmets
如何使用 C# 在 .NET 中获取当前用户名?
【问题讨论】:
string userName = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
【讨论】:
Environment.UserName有什么不同?
Environment.UserName 将返回“RunAs”用户。
MessageBox.Show(Environment.UserName); 将其放入您的window_loaded 事件中,并使用 RunAs 运行它....
Domain\Username。如何获取与用户名关联的名称?
如果您在用户网络中,则用户名将不同:
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 看似相同的结果。现在,你问有什么区别......我不确定。
System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split( '\\' ).Last();
Last()之前需要在Split之后添加ToArray()
ToArray()。不过你需要using System.Linq;。
System.Security.Principal.WindowsIdentity.GetCurrent().Name.Split( '\\' )[1];.
试试属性:Environment.UserName。
【讨论】:
string userName = Environment.UserName;
Environment.UsernName 给出了登录的帐户名,但WindowsIdentity.GetCurrent().Name 正在返回应用程序运行的帐户名.
Environment.UserName 的文档似乎有点矛盾:
在同一页上写着:
获取当前登录到 Windows 操作系统的人的用户名。
与
显示启动当前线程的人的用户名
如果您使用 RunAs 测试 Environment.UserName,它将为您提供 RunAs 用户帐户名称,而不是最初登录到 Windows 的用户。
【讨论】:
我完全赞同其他答案,但我想强调另一种方法
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(在本地服务器上运行应用程序时)。
【讨论】:
Request 仅适用于 Web 应用程序。这是System.Web.HttpRequest的一个实例@
用途:
System.Security.Principal.WindowsIdentity.GetCurrent().Name
这将是登录名。
【讨论】:
String myUserName = Environment.UserName
这将为您提供输出 - your_user_name
【讨论】:
以防万一有人在寻找用户显示名称,而不是用户名,比如我。
这是款待:
System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName
在您的项目中添加对System.DirectoryServices.AccountManagement 的引用。
【讨论】:
您可能还想尝试使用:
Environment.UserName;
像这样...:
string j = "Your WindowsXP Account Name is: " + Environment.UserName;
希望这对您有所帮助。
【讨论】:
我从现有答案中尝试了几种组合,但他们给了我
DefaultAppPool
IIS APPPOOL
IIS APPPOOL\DefaultAppPool
我最终使用了
string vUserName = User.Identity.Name;
它只给了我实际用户的域用户名。
【讨论】:
对实际登录的用户使用System.Windows.Forms.SystemInformation.UserName,因为Environment.UserName仍然返回当前进程正在使用的帐户。
【讨论】:
我已经尝试了所有以前的答案并在 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 返回登录的用户。只是需要提防。
【讨论】:
试试这个
ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
ManagementObjectCollection collection = searcher.Get();
string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
现在看起来好多了
【讨论】:
这是代码(但不是 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;
}
}
【讨论】:
对于要分发给多个用户的 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;
}
}
}
【讨论】:
获取当前的 Windows 用户名:
using System;
class Sample
{
public static void Main()
{
Console.WriteLine();
// <-- Keep this information secure! -->
Console.WriteLine("UserName: {0}", Environment.UserName);
}
}
【讨论】:
如果对其他人有帮助,当我将应用程序从 c#.net 3.5 应用程序升级到 Visual Studio 2017 时,这行代码 User.Identity.Name.Substring(4); 抛出此错误“startIndex 不能大于字符串长度"(它之前没有退缩)。
当我将其更改为 System.Security.Principal.WindowsIdentity.GetCurrent().Name 时很高兴,但是我最终使用 Environment.UserName; 来获取登录的 Windows 用户并且没有域部分。
【讨论】:
我在这里查看了大部分答案,但没有一个给我正确的用户名。
在我的情况下,我想在从其他用户运行我的应用程序时获取登录的用户名,例如当 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!");
}
【讨论】: