如何在C#中获取登录SID

如何在C#.net中检索Windows登录SID? (不是用户SID,而是每个会话的唯一新SID)

我担心你不得不求助于使用P / Invoke。 有一个例子如何在pinvoke.net上做(请参见页面底部):

 Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenSessionId , TokenInformation , TokenInfLength , out TokenInfLength ); 

请注意,我通过改变一行改变了示例,我用TOKEN_INFORMATION_CLASS.TokenUser替换了TOKEN_INFORMATION_CLASS.TokenUser ,这正是您所需要的。

希望这可以帮助。

更新:这是工作(至少在我的机器上)代码:

 using System; using System.Runtime.InteropServices; using System.Security.Principal; namespace LinqTest { public class ClsLookupAccountName { public const uint SE_GROUP_LOGON_ID = 0xC0000000; // from winnt.h public const int TokenGroups = 2; // from TOKEN_INFORMATION_CLASS enum TOKEN_INFORMATION_CLASS { TokenUser = 1, TokenGroups, TokenPrivileges, TokenOwner, TokenPrimaryGroup, TokenDefaultDacl, TokenSource, TokenType, TokenImpersonationLevel, TokenStatistics, TokenRestrictedSids, TokenSessionId, TokenGroupsAndPrivileges, TokenSessionReference, TokenSandBoxInert, TokenAuditPolicy, TokenOrigin } [StructLayout(LayoutKind.Sequential)] public struct SID_AND_ATTRIBUTES { public IntPtr Sid; public uint Attributes; } [StructLayout(LayoutKind.Sequential)] public struct TOKEN_GROUPS { public int GroupCount; [MarshalAs(UnmanagedType.ByValArray, SizeConst = 1)] public SID_AND_ATTRIBUTES[] Groups; }; // Using IntPtr for pSID instead of Byte[] [DllImport("advapi32", CharSet = CharSet.Auto, SetLastError = true)] static extern bool ConvertSidToStringSid(IntPtr pSID, out IntPtr ptrSid); [DllImport("kernel32.dll")] static extern IntPtr LocalFree(IntPtr hMem); [DllImport("advapi32.dll", SetLastError = true)] static extern bool GetTokenInformation( IntPtr TokenHandle, TOKEN_INFORMATION_CLASS TokenInformationClass, IntPtr TokenInformation, int TokenInformationLength, out int ReturnLength); public static string GetLogonId() { int TokenInfLength = 0; // first call gets lenght of TokenInformation bool Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenGroups, IntPtr.Zero, TokenInfLength, out TokenInfLength); IntPtr TokenInformation = Marshal.AllocHGlobal(TokenInfLength); Result = GetTokenInformation(WindowsIdentity.GetCurrent().Token, TOKEN_INFORMATION_CLASS.TokenGroups, TokenInformation, TokenInfLength, out TokenInfLength); if (!Result) { Marshal.FreeHGlobal(TokenInformation); return string.Empty; } string retVal = string.Empty; TOKEN_GROUPS groups = (TOKEN_GROUPS)Marshal.PtrToStructure(TokenInformation, typeof(TOKEN_GROUPS)); int sidAndAttrSize = Marshal.SizeOf(new SID_AND_ATTRIBUTES()); for (int i = 0; i < groups.GroupCount; i++) { SID_AND_ATTRIBUTES sidAndAttributes = (SID_AND_ATTRIBUTES)Marshal.PtrToStructure( new IntPtr(TokenInformation.ToInt64() + i * sidAndAttrSize + IntPtr.Size), typeof(SID_AND_ATTRIBUTES)); if ((sidAndAttributes.Attributes & SE_GROUP_LOGON_ID) == SE_GROUP_LOGON_ID) { IntPtr pstr = IntPtr.Zero; ConvertSidToStringSid(sidAndAttributes.Sid, out pstr); retVal = Marshal.PtrToStringAuto(pstr); LocalFree(pstr); break; } } Marshal.FreeHGlobal(TokenInformation); return retVal; } } } 

NB我在我的x64机器上测试过,所以请密切关注TokenInformation.ToInt64()代码段,也许你应该用TokenInformation.ToInt32()替换它

System.Security.Principal.WindowsIdentity.GetCurrent()。User.AccountDomainSid – 可能会做到这一点?

我知道这是一个老post。 刚遇到这个问题,因为我必须得到ICA会话ID和RDP会话ID才能让程序为每种类型的远程连接收集正确的变量。 当前会话ID位于Regedit HKEY_CURRENT_USER \ Remote *中。 由于我找不到任何WTS的替代品,我在这里发布我的解决方案。

  // Prints out ICA or RDP session ID of current user using System; using Microsoft.Win32; namespace ViaRegedit { class Program03 { static void Main(string[] args) { // Obtain an instance of RegistryKey for the CurrentUser registry RegistryKey rkCurrentUser = Registry.CurrentUser; // Obtain the test key (read-only) and display it. RegistryKey rkTest = rkCurrentUser.OpenSubKey("Remote"); foreach (string valueName in rkTest.GetSubKeyNames()) { //Getting path to RDP/Citrix session ID string RDPICApath = ""; if (rkTest.OpenSubKey(valueName) != null && rkTest.OpenSubKey(valueName) != null) { RDPICApath = rkTest.OpenSubKey(valueName).ToString(); } Console.WriteLine("Getting CurrentUser ICA-RDP path from string = " + RDPICApath); //Seperating RDPICApath to get session number string RDPICAnumber = RDPICApath.Substring(RDPICApath.LastIndexOf('\\') + 1); Console.WriteLine("Current User RDPICAnumber = " + RDPICAnumber); } rkTest.Close(); rkCurrentUser.Close(); Console.ReadLine(); } } }