获取c#中包含非英语字符的Windows用户名

本文关键字:Windows 用户 字符 英语 包含非 获取 | 更新日期: 2023-09-27 18:21:29

我们使用这篇文章中的代码来获取连接的windows用户的名称,以便断开它们的连接。

简而言之,GetUserName()、GetCurrentUserName(()、LogOffUser()和LogOffCurrentUser(),如下所示。

问题:在英文版的Windows下,当用户名包含非英文字符时,用户将不会注销。

经过调试,我们发现GetUserName()中的用户名显示为问号,而不是非放大字符,但在LogOffCurrentUser()中显示正确。因此,用户保持连接,因为在尝试断开连接时找不到用户名。

有什么办法解决这个问题吗?

public static string GetUserName(int sessionId, IntPtr server)
    {
        IntPtr buffer = IntPtr.Zero;
        uint count = 0;
        string userName = string.Empty;
        try
        {
            WTSQuerySessionInformation(server, sessionId, WTS_INFO_CLASS.WTSUserName, out buffer, out count);
            userName = Marshal.PtrToStringAnsi(buffer).ToUpper().Trim();
        }
        finally
        {
            WTSFreeMemory(buffer);
        }
        return userName;
    }
//-------------------------------------
public static string GetCurrentUserName()
    {
        ManagementObjectSearcher searcher = new ManagementObjectSearcher("SELECT UserName FROM Win32_ComputerSystem");
        ManagementObjectCollection collection = searcher.Get();
        string username = (string)collection.Cast<ManagementBaseObject>().First()["UserName"];
        string[] parts = username.Split(new char[] { '''' });
        if (parts[parts.Length - 1] == "SYSTEM") parts[parts.Length - 1] = "";
        return parts[parts.Length - 1];
    }
//-------------------------------------
public static bool LogOffUser(string userName, IntPtr server)
    {
        userName = userName.Trim().ToUpper();
        List<int> sessions = GetSessionIDs(server);
        Dictionary<string, int> userSessionDictionary = GetUserSessionDictionary(server, sessions);
        if (userSessionDictionary.ContainsKey(userName))
        {
            return WTSLogoffSession(server, userSessionDictionary[userName], false);
        }
        else
        {
            return false;
        }
    }
//-------------------------------------
public static void LogOffCurrentUser()
    {
        LogOffUser(GetCurrentUserName(), IntPtr.Zero);
    }

获取c#中包含非英语字符的Windows用户名

解决方案:

当试图获取包含非英语(非拉丁)字符的windows用户名时,必须p/调用WTSQuerySessionInformation的unicode版本,该版本为WTSQuerySessionInformation W

然后可以使用Marshal.PtrToStringUniMarshal.PtrToStringAuto将用户名放置到字符串中。

通过这种方式,WTSLogoffSession将在会话字典中找到用户名,并正确断开用户连接。