2010-03-17 8 views

ответ

4

Поскольку это в окне использовать NetStat, чтобы проверить, какие машины вы подключены к и на какие порты и просто разобрать адрес тот, который использует порт, который использует удаленный рабочий стол.

+0

И поскольку удаленный рабочий стол всегда использует порт 3389, это будет работать. Благодаря! – Vegar

+2

Это будет работать, только если у вас есть одно удаленное соединение, иначе вы не сможете увидеть, какие сеансы подключаются к удаленной машине. –

+1

Является ли вывод 'netstat' затронутым текущим языком? Это может сделать синтаксический анализ * намного сложнее. Предпочитайте решение API над тем, которое зависит от внешних программ и переменных выходных форматов. –

9

@Vegar, вы можете использовать функции WTSEnumerateSessions и WTSQuerySessionInformation для получения этой информации.

проверьте этот link для примера, используя Jedi Api Headers.

проверить этот код.

program ProjectTsInfo; 

{$APPTYPE CONSOLE} 

Uses 
    Windows, 
    JwaWinType, 
    JwaWtsApi32, 
    JwaWinsock2, 
    SysUtils, 
    TypInfo; 


type 
    PWtsSessionInfoAArray = ^TWtsSessionInfoAArray; 
    TWtsSessionInfoAArray = array[0..ANYSIZE_ARRAY-1] of WTS_SESSION_INFOA; 

//Get the info for all clients connected 
procedure GetAll_TSClientsInfo; 
var 
    SessionInfoAArray: PWtsSessionInfoAArray; 
    ClientAddr  : PWtsClientAddress; 
    ClientName  : PAnsiChar; 
    //ClientInfo  : PWTSCLIENT; 
    RetBytes   : Cardinal; 
    IPAddr   : String; 
    i    : integer; 
    pCount   : Cardinal; 
    SessionId  : Cardinal; 
begin 

    if WtsEnumerateSessions(WTS_CURRENT_SERVER, 0, 1, PWTS_SESSION_INFO(SessionInfoAArray), pCount) then 
    begin 

    for i := 0 to pCount - 1 do 
    begin 
     SessionId:=SessionInfoAArray^[i].SessionId; 
     WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientAddress, Pointer(ClientAddr), RetBytes); 
     WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientName, Pointer(ClientName), RetBytes); 
     //WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientInfo, Pointer(ClientInfo), RetBytes); //This value is supported for Windows Server 2008 and Windows Vista with SP1. 

    try 
     case ClientAddr^.AddressFamily of 
     AF_INET: 
      IPAddr:= Format('%d.%d.%d.%d', [ 
      ClientAddr^.Address[2], 
      ClientAddr^.Address[3], 
      ClientAddr^.Address[4], 
      ClientAddr^.Address[5] 
      ]); 
     else 
     IPAddr:= '<unknow>'; 
     end; 

     WriteLn(Format('Session Id : %d ', [SessionId])); 
     WriteLn(Format('Client Name : %s ', [ClientName])); 
     WriteLn(Format('Station Name: %s ', [SessionInfoAArray^[i].pWinStationName])); 
     WriteLn(Format('State  : %s ', [GetEnumName(TypeInfo(WTS_CONNECTSTATE_CLASS),integer(SessionInfoAArray^[i].State))])); 
     WriteLn(Format('IP   : %s ', [IPAddr])); 

     //supported for Windows Server 2008 and Windows Vista with SP1. 
     { 
     WriteLn(Format('ClientName  : %s ', [ClientInfo^.ClientName])); 
     WriteLn(Format('Domain   : %s ', [ClientInfo^.Domain])); 
     WriteLn(Format('UserName  : %s ', [ClientInfo^.UserName])); 
     WriteLn(Format('WorkDirectory : %s ', [ClientInfo^.WorkDirectory])); 
     WriteLn(Format('InitialProgram : %s ', [ClientInfo^.InitialProgram])); 
     WriteLn(Format('EncryptionLevel : %d ', [ClientInfo^.EncryptionLevel])); 
     WriteLn(Format('HRes   : %d ', [ClientInfo^.HRes])); 
     WriteLn(Format('VRes   : %d ', [ClientInfo^.VRes])); 
     WriteLn(Format('ColorDepth  : %d ', [ClientInfo^.ColorDepth])); 
     WriteLn(Format('ClientDirectory : %s ', [ClientInfo^.ClientDirectory])); 
     } 
     Writeln(''); 

    finally 
     WTSFreeMemory(ClientAddr); 
     WTSFreeMemory(ClientName); 
    end; 
    end; 
    end; 

    WtsFreeMemory(SessionInfoAArray); 
end; 

//Get the ip address of the actual connected client 
function GetIpActualClient : string; 
var 
    ClientAddr  : PWtsClientAddress; 
    RetBytes   : Cardinal; 
    IPAddr   : String; 
    SessionId  : Cardinal; 
begin 
     SessionId:=WTS_CURRENT_SESSION; 
     WTSQuerySessionInformation(WTS_CURRENT_SERVER, SessionId, WTSClientAddress, Pointer(ClientAddr), RetBytes); 
     try 
     case ClientAddr^.AddressFamily of 
      AF_INET: 
      IPAddr:= Format('%d.%d.%d.%d', [ 
       ClientAddr^.Address[2], 
       ClientAddr^.Address[3], 
       ClientAddr^.Address[4], 
       ClientAddr^.Address[5] 
       ]); 
      else 
      IPAddr:= '<unknow>'; 
     end; 
     Result:=IPAddr; 
     finally 
     WTSFreeMemory(ClientAddr); 
     end; 
end; 

begin 
    Writeln('IP Actual client '+GetIpActualClient); 
    Writeln('-----------------------------------'); 

    GetAll_TSClientsInfo; 
    Readln; 
end. 

UPDATE

Как говорит @Remko, то функция WTSQuerySessionInformation с WTSClientAddress типа, может вернуть локальный IP клиента. если вы хотите получить реальный ip, вы можете использовать вспомогательную функцию WinStationGetRemoteIPAddress, расположенную в блоке JwaWinSta.

Var 
Port : Word; 
IpAddr : WideString; 
Begin 
WinStationGetRemoteIPAddress(WTS_CURRENT_SERVER,WTS_CURRENT_SESSION,IpAddr,Port); 
End; 
+0

Нужно ли использовать 'WTSEnumerateSessions'? Я думаю, что использовать 'wts_Current_Session' для идентификатора сеанса будет достаточно. –

+0

Чтобы получить собственный сеанс, используйте ProcessIdToSessionId –

+0

@Rob вы правы, функция WTSEnumerateSessions - это получить информацию для всех сеансов, я разместил пример с использованием wts_Current_Session и WTSEnumerateSessions. ;) – RRUZ

4

WTSQuerySessionInformation возвращает клиенту IP, как клиент сообщает об этом, это, вероятно, будет (один) из его локального IP-адреса. Если вы хотите узнать IP-адрес REAL и порт, который подключен, вы можете использовать WinStationQueryInformationW с информационным классом WinStationRemoteAddress. Вам понадобится мое подразделение JwaWinsta от Jedi Apilib.

Я представил простую обертку в том же блоке, а также:

function WinStationGetRemoteIPAddress(hServer: HANDLE; SessionId: DWORD; 
    var RemoteIPAddress: WideString; var Port: WORD): Boolean; 
+0

+1 @Remko вы правы, WTSClientAddress может сообщить локальный ip вместо реального ip. Я обновляю свой ответ. p.s: Большое спасибо за отличную работу в Jedi Api Headers. ;) – RRUZ

+0

@RRUZ: Добро пожаловать! – Remko

3

Для меня это работало, он получает название аппарата, подключенного.

Environment.GetEnvironmentVariable("CLIENTNAME") 
0

Если вы хотите получить идентификатор удаленного сеанса и получить IP-адрес, подключенный через Citrix, вы можете использовать приведенное ниже. Это было разработано для запуска, когда пользователь подключается к серверу через сеанс citrix и отображает/создает строку для IP-адреса, с которого он подключается.

// Prints out ICA or RDP session ID of current user & gets ICA session clientAddress variable 

using System; 
using Microsoft.Win32; 

namespace ViaRegedit 
{ 
    class Program03 
    { 
     static void Main(string[] args) 
     { 
      // Obtain an instance of RegistryKey for the CurrentUser registry 
      RegistryKey rkCurrentUser = Registry.CurrentUser; 
      // Obtain the test key (read-only) and display it. 
      RegistryKey rkTest = rkCurrentUser.OpenSubKey("Remote"); 

      foreach (string valueName in rkTest.GetSubKeyNames()) 
      { 
       //Getting path to RDP/Citrix session ID 
       string RDPICApath = ""; 
       if (rkTest.OpenSubKey(valueName) != null && rkTest.OpenSubKey(valueName) != null) { RDPICApath = rkTest.OpenSubKey(valueName).ToString(); } 
       Console.WriteLine("Getting CurrentUser ICA-RDP path from string = " + RDPICApath); 

       //Split RDPICApath to get session number 
       string RDPICAnumber = RDPICApath.Substring(RDPICApath.LastIndexOf('\\') + 1); 
       Console.WriteLine("Current User RDPICAnumber = " + RDPICAnumber); 

       //Getting reg local machine info for Citrix based on RDP/Citrix session ID "RDPICAnumber" 
       string regLocal = @"SOFTWARE\Citrix\Ica\Session\" + RDPICAnumber + @"\Connection"; 
       RegistryKey localKey = RegistryKey.OpenBaseKey(Microsoft.Win32.RegistryHive.LocalMachine, RegistryView.Registry64); 
       RegistryKey citrixKey = localKey.OpenSubKey(regLocal); 
       Console.WriteLine("Registry " + citrixKey + " Does Exist - going to get ClientAddress"); 
       //getting clietAddress var from citrixKey 
       string clientAddress = ""; 
       if (citrixKey != null && citrixKey.GetValue("clientAddress") != null) 
        {clientAddress = citrixKey.GetValue("clientAddress").ToString();} 
        Console.WriteLine("Getting current user clientAddress from string = " + clientAddress); 
      } 
      rkTest.Close(); 
      rkCurrentUser.Close(); 
      Console.ReadLine(); 
     } 
    } 

} 
Смежные вопросы