tags:

views:

54

answers:

3

System.Environment.UserName internally calls

[DllImport("advapi32.dll", CharSet=CharSet.Auto)] internal static extern bool GetUserName(StringBuilder lpBuffer, ref int nSize);

Each call seems to hit AD, thus network latency and AD query effect speed of execution.

Would you know if there is a better way to retrieve this value?

Something like a cached SID somewhere on the Thread maybe? So I could read UserName & SID and cache these locally (for the time of execution) and only query System.Environment.UserName when I will get new SID (or something along these lines).

Thanks,

+1  A: 

Retrieves the user's WindowsIdentity. Name property retrieves the Domain\Name and User.Value the SID.

System.Security.Principal.WindowsIdentity.GetCurrent()
rdkleine
This one is well slower, need to create WindowsIdentity, internally calls KerbS4ULogon and after several other calls on LSA area of WinAPI finishes with LsaLogonUser.Definitely to heavy - I'm looking for something cached somewhere locally.
stic
A: 

I don't know if this fits to your needs, but maybe:

System.Environment.GetEnvironmentVariable("username");        
Frank Bollack
You know what System.Environment.UserName does, don't you? :-)
stic
@stic: I know what it is used for. Can you elaborate on your special requirements you have on an alternative to `System.Environment.UserName`?
Frank Bollack
@Frank Bollack: I think that stic is implying that `System.Environment.UserName` actually calls `GetEnvironmentVariable` (but I do not know -- I do not know a thing about .NET...).
Andreas Rejbrand
Andreas, you are right these two will give diffrent results in most (little more sophisticated) cases.Frank - for a case in which you care about reading this value (you expect it to change) reading environment is rather pointless. Otherwise, I would read it once and store in a local variable or sth like that
stic
@stic: I see your point, but that was not entirely clear from your question.@Andreas: `System.Environment.UserName` definitively isn't based on environment variable. Environment variables are initialized once on program startup. But as you can see from stics question, `System.Environment.UserName` is resolved at runtime via Win32 API calls.
Frank Bollack
A: 

Code bellow seems to do the trick.

First get current principal on thread if not set already. each next time just use it, adds small overhead to the thread itself, but doesn't call AD each time.

Any thoughts?

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

userName = System.Threading.Thread.CurrentPrincipal.Identity.Name;
stic