簡體   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