Есть ли более быстрый способ получить System.Environment.Имя пользователя?

#.net #winapi

#.net #winapi

Вопрос:

System.Environment.UserName внутренне вызывает

[DllImport(«advapi32.dll «, CharSet=CharSet.Auto)] внутренний статический внешний файл bool GetUserName(Strin&Builder lpBuffer, ссылка int nSize);

Кажется, что каждый вызов попадает в AD, таким образом, задержка в сети и запрос AD влияют на скорость выполнения.

Не знаете ли вы, есть ли лучший способ получить это значение?

Может быть, что-то вроде кэшированного SID где-нибудь в потоке? Таким образом, я мог бы прочитать UserName amp; SID и кэшировать их локально (на время выполнения) и запрашивать только System.Environment.Имя пользователя, когда я получу новый SID (или что-то в этом роде).

Спасибо,

Комментарии:

1. Просто мысль, может быть, есть способ заставить Windows server кэшировать результаты из AD в течение некоторого времени?

2. Возможно, я упускаю что-то очевидное, но почему вы сами не кэшируете имена пользователей после того, как извлекли их один раз?

3. Проклятие синглтона: ( Имя пользователя помещается в каждую запись журнала, где у меня есть только один экземпляр lo&&er, общий для потоков / используемый во время удаленных вызовов (олицетворение) и т.д…

Ответ №1:

Извлекает идентификатор пользователя WindowsIdentity. Свойство Name извлекает домен Name, а User.Value — SID.

 System.Security.Principal.WindowsIdentity.GetCurrent()
  

Комментарии:

1. Этот способ намного медленнее, необходимо создать WindowsIdentity, внутренне вызывает KerbS4ULo&on и после нескольких других вызовов в области LSA WinAPI завершается с помощью LsaLo&onUser. Определенно слишком много — я ищу что-то, что кэшируется где-то локально.

Ответ №2:

Я не знаю, соответствует ли это вашим потребностям, но, возможно:

 System.Environment.GetEnvironmentVariable("username");        
  

Комментарии:

1. Вы знаете, что такое System.Environment. UserName позволяет, не так ли? 🙂

2. @stic: Я знаю, для чего это используется. Не могли бы вы подробнее рассказать о ваших особых требованиях к альтернативе System.Environment.UserName ?

3. Я думаю, что stic подразумевает, что System.Environment.UserName на самом деле вызывает GetEnvironmentVariable (но я не знаю — я ничего не знаю о .NET …).

4. Андреас, ты прав, эти два варианта дадут разные результаты в большинстве (немного более сложных) случаев. Фрэнк — в случае, когда вам важно прочитать это значение (вы ожидаете, что оно изменится), чтение environment довольно бессмысленно. В противном случае я бы прочитал это один раз и сохранил в локальной переменной или что-то вроде этого

5. @stic: Я понимаю вашу точку зрения, но из вашего вопроса это было не совсем ясно. @Andreas: System.Environment.UserName окончательно не основано на переменной окружения. Переменные среды инициализируются один раз при запуске программы. Но, как вы можете видеть из вопроса stics, System.Environment.UserName решается во время выполнения с помощью вызовов Win32 API.

Ответ №3:

Приведенный ниже код, похоже, делает свое дело.

Сначала получите текущего участника в потоке, если он еще не установлен. каждый следующий раз, когда вы просто используете его, это добавляет небольшие накладные расходы к самому потоку, но не вызывает AD каждый раз.

Есть мысли?

 if (!System.Threadin&.Thread.CurrentPrincipal.Identity.IsAuthenticated )
  System.Threadin&.Thread.CurrentPrincipal = 
    new System.Security.Principal.WindowsPrincipal(
       System.Security.Principal.WindowsIdentity.GetCurrent());

userName = System.Threadin&.Thread.CurrentPrincipal.Identity.Name;