I went over most of the answers here and none of them gave me the right user name.
In my case I wanted to get the logged in user name, while running my app from a different user, like when shift+right click on a file and «Run as a different user».
The answers I tried gave me the ‘other’ username.
This blog post supplies a way to get the logged in user name, which works even in my scenario:
https://smbadiwe.github.io/post/track-activities-windows-service/
It uses Wtsapi
Edit: the essential code from the blog post, in case it ever disappears, is
Add this code to a class inheriting from 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;
}
If you don’t have one already, add a constructor to the class; and add this line to it:
CanHandleSessionChangeEvent = true;
EDIT:
Per comments requests, here’s how I get the session ID — which is the active console session 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!");
}
In .NET, there appears to be several ways to get the current Windows user name. Three of which are:
string name = WindowsIdentity.GetCurrent().Name;
or
string name = Thread.CurrentPrincipal.Identity.Name;
or
string name = Environment.UserName;
What’s the difference, and why choose one method over the other? Are there any other ways?
Amit Joshi
15.5k21 gold badges77 silver badges141 bronze badges
asked Jul 4, 2010 at 14:43
2
Environment.UserName calls GetUserName within advapi32.dll. This means that if you’re impersonating another user, this property will reflect that.
Thread.CurrentPrincipal has a setter and can be changed programmatically. (This is not impersonation btw.)
WindowsIdentity is your current windows identity, if any. It will not necessarily reflect the user, think ASP.NET with FormsAuthentication. Then the WindowsIdentity will be the NT-service, but the FormsIdentity will be the logged in user. There’s also a PassportIdentity, and you can build your own stuff to complicate things further.
answered Jul 4, 2010 at 19:19
sisvesisve
19.5k3 gold badges53 silver badges95 bronze badges
2
You asked for alternative ways.
Of course, you can always use the native Windows API: GetUserName.
answered Jul 4, 2010 at 19:15
Andreas RejbrandAndreas Rejbrand
106k8 gold badges282 silver badges384 bronze badges
I believe the property was put in several places so that it would be easier for the programmer to find. There’s only one logged in user, and only one respective name.
answered Jul 4, 2010 at 19:11
2
The three methods are described as follow:
HttpContext = HttpContext.Current.User, which returns an IPrincipal object that contains security information for the current Web request. This is the authenticated Web client.
WindowsIdentity = WindowsIdentity.GetCurrent(), which returns the identity of the security context of the currently executing Win32 thread.
Thread = Thread.CurrentPrincipal which returns the principal of the currently executing .NET thread which rides on top of the Win32 thread.
And they change in result depending on your IIS configuration as explained in this article:
http://msdn.microsoft.com/en-us/library/aa302377.aspx
answered Sep 4, 2013 at 8:23
I went over most of the answers here and none of them gave me the right user name.
In my case I wanted to get the logged in user name, while running my app from a different user, like when shift+right click on a file and «Run as a different user».
The answers I tried gave me the ‘other’ username.
This blog post supplies a way to get the logged in user name, which works even in my scenario:
https://smbadiwe.github.io/post/track-activities-windows-service/
It uses Wtsapi
Edit: the essential code from the blog post, in case it ever disappears, is
Add this code to a class inheriting from 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;
}
If you don’t have one already, add a constructor to the class; and add this line to it:
CanHandleSessionChangeEvent = true;
EDIT:
Per comments requests, here’s how I get the session ID — which is the active console session 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!");
}
Кстати, в дополнение к вопросу:
Можно следить за появлением explorer.exe и опред. с какими правами он запущен.
Таким образом, как только заходит другой юзер, запускается соотв. explorer.exe с его правами.
Но задача конечно в другом… Нам нужно ловить то событие когда именно переключаются учётные записи. Вошло может и 2, а работать может ток 1. Задача хотя б определить того, кто работает, если вошло несколько.
Добавлено через 1 минуту
Сообщение от OwenGlendower
тогда тебе должны подойти варианты кода приведенные в первом сообщении
Не подходит.. Я запускаю приложение с правами Админа из под другой учётки и это самое выводит, что я — админ…
Добавлено через 36 секунд
Т.е. по сути определяет с чьими правам я запускаю приложение.
Добавлено через 20 секунд
А надо — работающего юзверя
Хочу получить имя юзера текущей сессии Windows, но ничего не выходит.
char buffer[256]; // буфер
DWORD size; // размер
size = sizeof(buffer); // размер буфера
GetUserName(buffer, &size);
string userName = buffer;
Ошибку выкидывает в 4 строке, типо char buffer не соответствует типу LPWSTR.
Хотя в книжке написано так.
-
Вопрос задан
-
4225 просмотров
Windows ведь. В заголовках фунция определена так:
BOOL WINAPI GetUserNameW(LPWSTR lpBuffer, LPDWORD lpnSize);
BOOL WINAPI GetUserNameA(LPSTR lpBuffer, LPDWORD lpnSize);
#ifdef _UNICODE
#define GetUserName GetUserNameW
#else
#define GetUserName GetUserNameA
#endif
Решения на выбор:
- Убрать в настройках компиляции определение _UNICODE
- Использовать GetUserNameA
- Переписать с использованием TCHAR, size при этом должен быть sizeof(buffer) / sizeof(*buffer)
И да asd111 прав буфер обязан быть размером UNLEN+1, иначе может случится переполнение буфера, хоть это и маловероятно.
Пригласить эксперта
#include <windows.h>
#include <Lmcons.h>
char username[UNLEN+1];
DWORD username_len = UNLEN+1;
GetUserName(username, &username_len);
-
Показать ещё
Загружается…
09 окт. 2023, в 16:50
30000 руб./за проект
09 окт. 2023, в 16:48
500 руб./в час
09 окт. 2023, в 16:18
1000 руб./в час