1

现在我有代码可以检测通过远程桌面(mstsc.exe)连接到 Windows 到 Windows XP 的用户的会话 ID,但我想知道他们的用户名。

4

2 回答 2

0
[DllImport("wtsapi32.dll")]
static extern IntPtr WTSOpenServer([MarshalAs(UnmanagedType.LPStr)] String pServerName);

[DllImport("wtsapi32.dll")]
static extern void WTSCloseServer(IntPtr hServer);

[DllImport("wtsapi32.dll")]
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);

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

[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_INFO_CLASS
{
  WTSInitialProgram,
  WTSApplicationName,
  WTSWorkingDirectory,
  WTSOEMId,
  WTSSessionId,
  WTSUserName,
  WTSWinStationName,
  WTSDomainName,
  WTSConnectState,
  WTSClientBuildNumber,
  WTSClientName,
  WTSClientDirectory,
  WTSClientProductId,
  WTSClientHardwareId,
  WTSClientAddress,
  WTSClientDisplay,
  WTSClientProtocolType
}
public enum WTS_CONNECTSTATE_CLASS
{
  WTSActive,
  WTSConnected,
  WTSConnectQuery,
  WTSShadow,
  WTSDisconnected,
  WTSIdle,
  WTSListen,
  WTSReset,
  WTSDown,
  WTSInit
}
public static IntPtr OpenServer(String Name)
{
  IntPtr server = WTSOpenServer(Name);
  return server;
}
public static void CloseServer(IntPtr ServerHandle)
{
  WTSCloseServer(ServerHandle);
}
public static DataTable ListUsers(String ServerName)
{
    DataTable DtResult = new DataTable();
    DtResult.Columns.Add("Domain");
    DtResult.Columns.Add("User");

  IntPtr serverHandle = IntPtr.Zero;
  List<String> resultList = new List<string>();
  serverHandle = OpenServer(ServerName);

  try
  {
    IntPtr SessionInfoPtr = IntPtr.Zero;
    IntPtr userPtr = IntPtr.Zero;
    IntPtr domainPtr = IntPtr.Zero;
    Int32 sessionCount = 0;
    Int32 retVal = WTSEnumerateSessions(serverHandle, 0, 1, ref SessionInfoPtr, ref sessionCount);
    Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO));
    Int32 currentSession = (int)SessionInfoPtr;
    uint bytes = 0;

    if (retVal != 0)
    {
      for (int i = 0; i < sessionCount; i++)
      {
        WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)currentSession, typeof(WTS_SESSION_INFO));
        currentSession += dataSize;

        WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSUserName, out userPtr, out bytes);
        WTSQuerySessionInformation(serverHandle, si.SessionID, WTS_INFO_CLASS.WTSDomainName, out domainPtr, out bytes);
          DtResult.Rows.Add(Marshal.PtrToStringAnsi(domainPtr) ,Marshal.PtrToStringAnsi(userPtr));
        WTSFreeMemory(userPtr); 
        WTSFreeMemory(domainPtr);
      }

      WTSFreeMemory(SessionInfoPtr);
    }
  }
  finally
  {
    CloseServer(serverHandle);
  }

    return DtResult;
}
于 2013-06-27T06:23:17.993 回答
0

如果您想处理 P/Invokes,也可以使用Cassia 库。有关代码示例,请参阅此答案

于 2013-07-19T01:40:58.323 回答