#.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;