Как получить имя пользователя windows c

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's user avatar

Amit Joshi

15.5k21 gold badges77 silver badges141 bronze badges

asked Jul 4, 2010 at 14:43

Andy's user avatar

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

sisve's user avatar

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 Rejbrand's user avatar

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

Pavel Radzivilovsky's user avatar

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

Oskar Berggren's user avatar

answered Sep 4, 2013 at 8:23

Maurizio In denmark's user avatar

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 руб./в час

Минуточку внимания

  • Как получить доступ к папке windows old
  • Как получить код активации windows 10 бесплатно
  • Как получить доступ к папке windows apps
  • Как получить ключ продукта для windows 10 лицензионный ключ бесплатно
  • Как получить ключ для windows 10 pro лицензионный ключ бесплатно