2012-12-21 25 views
6

Tôi đang cố truy xuất một số thông tin đăng nhập RDC/RDP và "Console" theo lập trình thông qua C#.C# Nhận thông tin về RDC/RDP và "Bàn điều khiển" Phiên

Tôi muốn phát triển một ứng dụng giao diện điều khiển đơn giản (.EXE) sao cho tôi có thể truy xuất thông tin từ Trình quản lý tác vụ -> Tab người dùng của bất kỳ máy tính từ xa nào trên miền của chúng tôi (Windows Server 2003 x86 hoặc 2008R2 x64).

Điều này cho thấy nếu một người đăng nhập trực tiếp vào máy chủ (tức là Bảng điều khiển) hoặc trên RDC/RDP (bao gồm ứng dụng khách nếu vẫn hoạt động) hoặc ngắt kết nối nếu bị "tạm ngưng" (nghĩa là họ chưa đăng xuất nhưng chỉ đóng cửa sổ/RDP RDC tạm thời)

tôi có quyền quản trị trên tất cả các máy chủ và có thể cấu hình bất kỳ cửa sổ dịch vụ/tường lửa quy tắc mà cần phải được bật/tắt (nếu có yêu cầu)

tôi nghĩ rằng tôi phải có lẽ sử dụng WMI (sử dụng System.Management) nhưng các ví dụ tôi đã tìm thấy từ google chỉ lấy người dùng hiện tại.

//Method 1 
var searcher = new ManagementObjectSearcher(
       "SELECT UserName FROM Win32_ComputerSystem"); 
var collection = Searcher.Get(); 
foreach(ManagementObject entry in collection) 
{ 
    Console.WriteLine(entry["UserName"]); 
} 

//Method 2 
string computer = "somecomputername"; 
var searcher = new ManagementObjectSearcher(
       computer + @"root\CIMV2", "SELECT * FROM Win32_TerminalService"); 
var collection = Searcher.Get(); 
foreach(ManagementObject entry in collection) 
{ 
    //Write them out (although usernames isnt listed from the example I found) 
} 

Trả lời

19

Điều này sẽ cung cấp cho bạn mọi thứ bạn cần. Chỉ cần gọi ListSessions và chuyển tên máy chủ. Để nhận thêm thông tin về phiên, hãy chuyển số ServerNameSessionId đến GetSessionInfo.

using System; 
using System.Collections.Generic; 
using System.Text; 
using System.Runtime.InteropServices; 

namespace TerminalTools 
{ 
    public class TermServicesManager 
    { 

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

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

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

     [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); 

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

     [StructLayout(LayoutKind.Sequential)] 
     public struct WTS_CLIENT_ADDRESS 
     { 
      public uint AddressFamily; 
      [MarshalAs(UnmanagedType.ByValArray, SizeConst = 20)] 
      public byte[] Address; 
     } 

     [StructLayout(LayoutKind.Sequential)] 
     public struct WTS_CLIENT_DISPLAY 
     { 
      public uint HorizontalResolution; 
      public uint VerticalResolution; 
      public uint ColorDepth; 
     } 

     public enum WTS_CONNECTSTATE_CLASS 
     { 
      Active, 
      Connected, 
      ConnectQuery, 
      Shadow, 
      Disconnected, 
      Idle, 
      Listen, 
      Reset, 
      Down, 
      Init 
     } 

     public enum WTS_INFO_CLASS 
     { 
      InitialProgram = 0, 
      ApplicationName = 1, 
      WorkingDirectory = 2, 
      OEMId = 3, 
      SessionId = 4, 
      UserName = 5, 
      WinStationName = 6, 
      DomainName = 7, 
      ConnectState = 8, 
      ClientBuildNumber = 9, 
      ClientName = 10, 
      ClientDirectory = 11, 
      ClientProductId = 12, 
      ClientHardwareId = 13, 
      ClientAddress = 14, 
      ClientDisplay = 15, 
      ClientProtocolType = 16 
     } 

         private static IntPtr OpenServer(string Name) 
    { 
     IntPtr server = WTSOpenServer(Name); 
     return server; 
    } 

        private static void CloseServer(IntPtr ServerHandle) 
    { 
     WTSCloseServer(ServerHandle); 
    } 

     public static List<TerminalSessionData> ListSessions(string ServerName) 
     { 
      IntPtr server = IntPtr.Zero; 
      List<TerminalSessionData> ret = new List<TerminalSessionData>(); 
      server = OpenServer(ServerName); 

      try 
      { 
       IntPtr ppSessionInfo = IntPtr.Zero; 

       Int32 count = 0; 
       Int32 retval = WTSEnumerateSessions(server, 0, 1, ref ppSessionInfo, ref count); 
       Int32 dataSize = Marshal.SizeOf(typeof(WTS_SESSION_INFO)); 

       Int64 current = (int)ppSessionInfo; 

       if (retval != 0) 
       { 
        for (int i = 0; i < count; i++) 
        { 
         WTS_SESSION_INFO si = (WTS_SESSION_INFO)Marshal.PtrToStructure((System.IntPtr)current, typeof(WTS_SESSION_INFO)); 
         current += dataSize; 

         ret.Add(new TerminalSessionData(si.SessionID, si.State, si.pWinStationName)); 
        } 

        WTSFreeMemory(ppSessionInfo); 
       } 
      } 
      finally 
      { 
       CloseServer(server); 
      } 

      return ret; 
     } 

     public static TerminalSessionInfo GetSessionInfo(string ServerName, int SessionId) 
     { 
      IntPtr server = IntPtr.Zero; 
      server = OpenServer(ServerName); 
      System.IntPtr buffer = IntPtr.Zero; 
      uint bytesReturned; 
      TerminalSessionInfo data = new TerminalSessionInfo(); 

      try 
      { 
       bool worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ApplicationName, out buffer, out bytesReturned); 

       if (!worked) 
        return data; 

       string strData = Marshal.PtrToStringAnsi(buffer); 
       data.ApplicationName = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientAddress, out buffer, out bytesReturned); 

       if (!worked) 
        return data; 

       WTS_CLIENT_ADDRESS si = (WTS_CLIENT_ADDRESS)Marshal.PtrToStructure((System.IntPtr)buffer, typeof(WTS_CLIENT_ADDRESS)); 
       data.ClientAddress = si; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientBuildNumber, out buffer, out bytesReturned); 

       if (!worked) 
        return data; 

       int lData = Marshal.ReadInt32(buffer); 
       data.ClientBuildNumber = lData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientDirectory, out buffer, out bytesReturned); 

       if (!worked) 
        return data; 

       strData = Marshal.PtrToStringAnsi(buffer); 
       data.ClientDirectory = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientDisplay, out buffer, out bytesReturned); 

       if (!worked) 
        return data; 

       WTS_CLIENT_DISPLAY cd = (WTS_CLIENT_DISPLAY)Marshal.PtrToStructure((System.IntPtr)buffer, typeof(WTS_CLIENT_DISPLAY)); 
       data.ClientDisplay = cd; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientHardwareId, out buffer, out bytesReturned); 

       if (!worked) 
        return data; 

       lData = Marshal.ReadInt32(buffer); 
       data.ClientHardwareId = lData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientName, out buffer, out bytesReturned); 
       strData = Marshal.PtrToStringAnsi(buffer); 
       data.ClientName = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientProductId, out buffer, out bytesReturned); 
       Int16 intData = Marshal.ReadInt16(buffer); 
       data.ClientProductId = intData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ClientProtocolType, out buffer, out bytesReturned); 
       intData = Marshal.ReadInt16(buffer); 
       data.ClientProtocolType = intData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.ConnectState, out buffer, out bytesReturned); 
       lData = Marshal.ReadInt32(buffer); 
       data.ConnectState = (WTS_CONNECTSTATE_CLASS)Enum.ToObject(typeof(WTS_CONNECTSTATE_CLASS), lData); 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.DomainName, out buffer, out bytesReturned); 
       strData = Marshal.PtrToStringAnsi(buffer); 
       data.DomainName = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.InitialProgram, out buffer, out bytesReturned); 
       strData = Marshal.PtrToStringAnsi(buffer); 
       data.InitialProgram = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.OEMId, out buffer, out bytesReturned); 
       strData = Marshal.PtrToStringAnsi(buffer); 
       data.OEMId = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.SessionId, out buffer, out bytesReturned); 
       lData = Marshal.ReadInt32(buffer); 
       data.SessionId = lData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.UserName, out buffer, out bytesReturned); 
       strData = Marshal.PtrToStringAnsi(buffer); 
       data.UserName = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.WinStationName, out buffer, out bytesReturned); 
       strData = Marshal.PtrToStringAnsi(buffer); 
       data.WinStationName = strData; 

       worked = WTSQuerySessionInformation(server, SessionId, 
        WTS_INFO_CLASS.WorkingDirectory, out buffer, out bytesReturned); 
       strData = Marshal.PtrToStringAnsi(buffer); 
       data.WorkingDirectory = strData; 
      } 
      finally 
      { 
       WTSFreeMemory(buffer); 
       buffer = IntPtr.Zero; 
       CloseServer(server); 
      } 

      return data; 
     } 

    } 

    public class TerminalSessionData 
    { 
     public int SessionId; 
     public TermServicesManager.WTS_CONNECTSTATE_CLASS ConnectionState; 
     public string StationName; 

          public TerminalSessionData(int sessionId, TermServicesManager.WTS_CONNECTSTATE_CLASS connState, string stationName) 
    { 
     SessionId = sessionId; 
     ConnectionState = connState; 
     StationName = stationName; 
    } 

        public override string ToString() 
    { 
     return String.Format("{0} {1} {2}", SessionId, ConnectionState, StationName); 
    } 
    } 

    public class TerminalSessionInfo 
    { 
     public string InitialProgram; 
     public string ApplicationName; 
     public string WorkingDirectory; 
     public string OEMId; 
     public int SessionId; 
     public string UserName; 
     public string WinStationName; 
     public string DomainName; 
     public TermServicesManager.WTS_CONNECTSTATE_CLASS ConnectState; 
     public int ClientBuildNumber; 
     public string ClientName; 
     public string ClientDirectory; 
     public int ClientProductId; 
     public int ClientHardwareId; 
     public TermServicesManager.WTS_CLIENT_ADDRESS ClientAddress; 
     public TermServicesManager.WTS_CLIENT_DISPLAY ClientDisplay; 
     public int ClientProtocolType; 
    } 
} 
+1

hi Hovercrafty này đang trở lại các dữ liệu chính xác (số lượng kết nối, Session ID và "loại kết nối") từ Người dùng Tab nhưng còn thiếu hai cột chính (từ người sử dụng Tab trong Task Manager) giá trị của tên người dùng và CLIENTNAME. Tôi đã vượt qua WTS_SESSION_INFO và/hoặc TerminalSessionData.SessionId vào một phương pháp khác để lấy hai cột này? – Kyle

+0

@Kyle Tôi đã cập nhật câu trả lời để bao gồm các phương pháp bạn cần để có được dữ liệu phiên bổ sung. –

+1

Câu trả lời rất hoàn chỉnh và chắc chắn đáng giá cao. –

Các vấn đề liên quan