/// <summary> /// Retrieve the UserName through PInvoke /// </summary> /// <param name="process"></param> /// <returns></returns> private static string RetrieveProcessUserName(Process process) { string userName = null; #if UNIX userName = Platform.NonWindowsGetUserFromPid(process.Id); #else IntPtr tokenUserInfo = IntPtr.Zero; IntPtr processTokenHandler = IntPtr.Zero; const uint TOKEN_QUERY = 0x0008; try { do { int error; if (!Win32Native.OpenProcessToken(ClrFacade.GetSafeProcessHandle(process), TOKEN_QUERY, out processTokenHandler)) { break; } // Set the default length to be 256, so it will be sufficient for most cases int tokenInfoLength = 256; tokenUserInfo = Marshal.AllocHGlobal(tokenInfoLength); if (!Win32Native.GetTokenInformation(processTokenHandler, Win32Native.TOKEN_INFORMATION_CLASS.TokenUser, tokenUserInfo, tokenInfoLength, out tokenInfoLength)) { error = Marshal.GetLastWin32Error(); if (error == Win32Native.ERROR_INSUFFICIENT_BUFFER) { Marshal.FreeHGlobal(tokenUserInfo); tokenUserInfo = Marshal.AllocHGlobal(tokenInfoLength); if (!Win32Native.GetTokenInformation(processTokenHandler, Win32Native.TOKEN_INFORMATION_CLASS.TokenUser, tokenUserInfo, tokenInfoLength, out tokenInfoLength)) { break; } } else { break; } } var tokenUser = ClrFacade.PtrToStructure <Win32Native.TOKEN_USER>(tokenUserInfo); // Set the default length to be 256, so it will be sufficient for most cases int userNameLength = 256, domainNameLength = 256; var userNameStr = new StringBuilder(userNameLength); var domainNameStr = new StringBuilder(domainNameLength); Win32Native.SID_NAME_USE accountType; if (!Win32Native.LookupAccountSid(null, tokenUser.User.Sid, userNameStr, ref userNameLength, domainNameStr, ref domainNameLength, out accountType)) { error = Marshal.GetLastWin32Error(); if (error == Win32Native.ERROR_INSUFFICIENT_BUFFER) { userNameStr.EnsureCapacity(userNameLength); domainNameStr.EnsureCapacity(domainNameLength); if (!Win32Native.LookupAccountSid(null, tokenUser.User.Sid, userNameStr, ref userNameLength, domainNameStr, ref domainNameLength, out accountType)) { break; } } else { break; } } userName = domainNameStr + "\\" + userNameStr; } while (false); } catch (NotSupportedException) { // The Process not started yet, or it's a process from a remote machine } catch (InvalidOperationException) { // The Process has exited, Process.Handle will raise this exception } catch (Win32Exception) { // We might get an AccessDenied error } catch (Exception) { // I don't expect to get other exceptions, } finally { if (tokenUserInfo != IntPtr.Zero) { Marshal.FreeHGlobal(tokenUserInfo); } if (processTokenHandler != IntPtr.Zero) { Win32Native.CloseHandle(processTokenHandler); } } #endif return(userName); }