繁体   English   中英

如何在 C# 控制台应用程序中获取当前 Windows 用户名?

[英]How do I get Current Windows Username in C# Console Application?

我的问题:

我正在开发一个独立控制台应用程序,它必须找到当前登录的活动 Windows 用户名。

测试用例:

  1. 多个用户登录并且只有一个用户处于活动状态。

  2. 一个用户当前处于活动状态,同时访问其他远程用户

  3. 远程用户中的其他用户与当前处于活动状态的用户相同。

登录顺序可能会有所不同,但在所有情况下都只需要当前的活动用户。

我为上述任务找到了这些代码:

string UserName1 = System.Security.Principal.WindowsIdentity.GetCurrent().Name; // Gives NT AUTHORITY\SYSTEM
string UserName2 = Request.LogonUserIdentity.Name; // Gives NT AUTHORITY\SYSTEM
string UserName3 = Environment.UserName; // Gives SYSTEM
string UserName4 = HttpContext.Current.User.Identity.Name; // Gives actual user logged on (as seen in <ASP:Login />)
string UserName5 = System.Windows.Forms.SystemInformation.UserName; // Gives SYSTEM
string DisplayName = System.DirectoryServices.AccountManagement.UserPrincipal.Current.DisplayName

我知道HttpContext不是纯粹基于控制台的,但如果它满足条件并且具有可比性,我会使用它。

我不知道所有可能的测试用例,也无法测试它们。

我不确定哪一个适合我所有的测试用例。

我会接受任何适合需求的解决方案。

帮我找到可能的方法。

抱歉有任何错误并感谢您的帮助。

我已经将 C 代码转换为 C# 并实现了它。

public static class UserInfo
    {
        #region PInvoke

        [DllImport("wtsapi32.dll", SetLastError = true)]
        static extern Int32 WTSEnumerateSessions(
            IntPtr hServer,
            [MarshalAs(UnmanagedType.U4)] Int32 Reserved,
            [MarshalAs(UnmanagedType.U4)] Int32 Version,
            ref IntPtr ppSessionInfo,
            [MarshalAs(UnmanagedType.U4)] ref Int32 pCount);

        [DllImport("wtsapi32.dll")]
        static extern void WTSFreeMemory(IntPtr pMemory);

        [StructLayout(LayoutKind.Sequential)]
        private struct WTS_SESSION_INFO
        {
            public Int32 SessionID;
            [MarshalAs(UnmanagedType.LPStr)]
            public String pWinStationName;
            public WTS_CONNECTSTATE_CLASS State;
        }

        public enum WTS_CONNECTSTATE_CLASS
        {
            WTSActive,
            WTSConnected,
            WTSConnectQuery,
            WTSShadow,
            WTSDisconnected,
            WTSIdle,
            WTSListen,
            WTSReset,
            WTSDown,
            WTSInit
        }

        [DllImport("Wtsapi32.dll")]
        public static extern bool WTSQuerySessionInformation(IntPtr hServer, int sessionId, WTSInfoClass wtsInfoClass, out IntPtr ppBuffer, out uint pBytesReturned);

        public enum WTSInfoClass
        {
            WTSInitialProgram,
            WTSApplicationName,
            WTSWorkingDirectory,
            WTSOEMId,
            WTSSessionId,
            WTSUserName,
            WTSWinStationName,
            WTSDomainName,
            WTSConnectState,
            WTSClientBuildNumber,
            WTSClientName,
            WTSClientDirectory,
            WTSClientProductId,
            WTSClientHardwareId,
            WTSClientAddress,
            WTSClientDisplay,
            WTSClientProtocolType,
            WTSIdleTime,
            WTSLogonTime,
            WTSIncomingBytes,
            WTSOutgoingBytes,
            WTSIncomingFrames,
            WTSOutgoingFrames,
            WTSClientInfo,
            WTSSessionInfo
        }

        [Flags]
        public enum LocalMemoryFlags
        {
            LMEM_FIXED = 0x0000,
            LMEM_MOVEABLE = 0x0002,
            LMEM_NOCOMPACT = 0x0010,
            LMEM_NODISCARD = 0x0020,
            LMEM_ZEROINIT = 0x0040,
            LMEM_MODIFY = 0x0080,
            LMEM_DISCARDABLE = 0x0F00,
            LMEM_VALID_FLAGS = 0x0F72,
            LMEM_INVALID_HANDLE = 0x8000,
            LHND = (LMEM_MOVEABLE | LMEM_ZEROINIT),
            LPTR = (LMEM_FIXED | LMEM_ZEROINIT),
            NONZEROLHND = (LMEM_MOVEABLE),
            NONZEROLPTR = (LMEM_FIXED)
        }

        [DllImport("kernel32.dll")]
        static extern IntPtr LocalAlloc(uint uFlags, UIntPtr uBytes);

        [DllImport("kernel32.dll", SetLastError = true)]
        static extern IntPtr LocalFree(IntPtr hMem);

        [DllImport("kernel32.dll", EntryPoint = "CopyMemory", SetLastError = false)]
        public static extern void CopyMemory(IntPtr dest, IntPtr src, uint count);

        #endregion PInvoke

        #region Helper Methods

        public static bool GetPhysicallyLoggedOnUserName(out string PhysicallyLoggedOnUserName, out string DomainName)
        {
            PhysicallyLoggedOnUserName = string.Empty;
            DomainName = string.Empty;
            IntPtr WTS_CURRENT_SERVER_HANDLE = (IntPtr)null;
            try
            {
                IntPtr ppSessionInfo = IntPtr.Zero;
                Int32 pCount = 0;
                Int32 retval = WTSEnumerateSessions(WTS_CURRENT_SERVER_HANDLE, 0, 1, ref ppSessionInfo, ref pCount);
                Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
                if (retval != 0)
                {
                    Int64 current = (int)ppSessionInfo;
                    int totalactiveuser = 0;
                    for (int i = 0; i < pCount; i++)
                    {
                        WTS_SESSION_INFO wts = (WTS_SESSION_INFO)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO));
                        current += dataSize;
                        if (wts.State == WTS_CONNECTSTATE_CLASS.WTSActive)
                        {
                            totalactiveuser++;
                        }
                    }

                    if (totalactiveuser < 1)
                    {
                        return false;
                    }

                    current = (int)ppSessionInfo;
                    for (int i = 0; i < pCount; i++)
                    {
                        WTS_SESSION_INFO wts = (WTS_SESSION_INFO)Marshal.PtrToStructure((IntPtr)current, typeof(WTS_SESSION_INFO));
                        current += dataSize;
                        if (wts.State != WTS_CONNECTSTATE_CLASS.WTSActive)
                        {
                            continue;
                        }

                        IntPtr szUserName = IntPtr.Zero;
                        uint dwLen = 0;
                        bool bStatus = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wts.SessionID, WTSInfoClass.WTSUserName, out szUserName, out dwLen);
                        if (bStatus)
                        {
                            IntPtr szUpn = LocalAlloc((uint)LocalMemoryFlags.LMEM_FIXED, new UIntPtr(unchecked((uint)szUserName.ToInt32())));
                            CopyMemory(szUpn, szUserName, (uint)IntPtr.Size);
                            LocalFree(szUpn);
                        }

                        IntPtr ProtoType = IntPtr.Zero;
                        bStatus = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wts.SessionID, WTSInfoClass.WTSClientProtocolType, out ProtoType, out dwLen);
                        int cpt = Marshal.ReadInt32(ProtoType);
                        WTSFreeMemory(ProtoType);
                        if (cpt == 0)   // WTS_PROTOCOL_TYPE_CONSOLE
                        {
                            PhysicallyLoggedOnUserName = Marshal.PtrToStringAnsi(szUserName);
                            WTSFreeMemory(szUserName);
                            dwLen = 0;
                            IntPtr szDomainName = IntPtr.Zero;
                            bStatus = WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, wts.SessionID, WTSInfoClass.WTSDomainName, out szDomainName, out dwLen);
                            DomainName = Marshal.PtrToStringAnsi(szDomainName);
                            WTSFreeMemory(szDomainName);
                            return true;
                        }

                        WTSFreeMemory(szUserName);
                    }
                }
            }
            catch
            {
                return false;
            }

            return false;
        }

        #endregion Helper Methods
    }

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM