我的问题:
我正在开发一个独立控制台应用程序,该应用程序必须找到当前登录的活动Windows用户名。
测试用例:
已登录多个用户,只有一个用户处于活动状态。
一个用户当前处于活动状态,也正在访问其他远程用户
远程用户中的其他用户与当前处于活动状态的用户相同。
登录顺序可能会有所不同,但是在所有情况下,仅需要当前活动用户。
我已经找到上述任务的以下代码:
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 并非纯粹基于控制台,但是如果满足条件且具有可比性,我将使用它。
我不知道所有可能的测试用例,也无法对其进行测试。
我不确定哪一个适合我的所有测试用例。
我将接受任何适合需要的解决方案。
帮我找到可能的方法。
很抱歉有任何错误,感谢您的帮助。
答案 0 :(得分:0)
我已经将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
}