2010-03-17 21 views

Respuesta

4

Ya que está en ventanas usar netstat para comprobar qué máquinas que está conectado a los puertos y sobre la que ya sólo analizar fuera de la dirección de la que utiliza el puerto que utiliza el escritorio remoto.

+0

Y dado que el escritorio remoto siempre usa el puerto 3389, esto funcionará. ¡Gracias! – Vegar

+2

Esto solo funcionaría si tiene una sola conexión remota, de lo contrario no podrá ver qué sesiones se conectan a qué máquina remota. –

+1

¿La salida de 'netstat' está afectada por la configuración regional actual? Eso puede hacer que el análisis sintáctico * mucho * sea más complicado. Prefiere una solución API sobre una que dependa de programas externos y formatos de salida variables. –

9

@Vegar, puede usar las funciones WTSEnumerateSessions y WTSQuerySessionInformation para recuperar esta información.

verifique esto link para ver un ejemplo usando el Jedi Api Headers.

marque este código.

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. 

ACTUALIZACIÓN

Como dice @Remko, la función deWTSQuerySessionInformation con el WTSClientAddress tipo, puede devolver la IP local del cliente. si quiere obtener la ip real, puede usar la función auxiliar WinStationGetRemoteIPAddress ubicada en la unidad JwaWinSta.

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

¿Es necesario usar 'WTSEnumerateSessions'? Creo que usar 'wts_Current_Session' para la ID de sesión sería suficiente. –

+0

Para obtener su propia sesión, use ProcessIdToSessionId –

+0

@Rob tiene razón la función WTSEnumerateSessions es obtener la información para todas las sesiones, publiqué un ejemplo usando wts_Current_Session y WTSEnumerateSessions. ;) – RRUZ

4

WTSQuerySessionInformation devuelve el cliente IP que el cliente indica que, éste será probablemente (uno) de su dirección IP local. Si desea conocer la dirección IP REAL y el puerto que está conectado, puede usar WinStationQueryInformationW con la clase de información WinStationRemoteAddress. Necesitarás mi unidad JwaWinsta del Jedi Apilib.

que he proporcionado un simple envoltorio de la misma unidad, así:

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

+1 @Remko tiene razón, el WTSClientAddress puede informar la dirección IP local en lugar de la dirección IP real. actualizo mi respuesta p.s: muchas gracias por su gran trabajo en los Jedi Api Headers. ;) – RRUZ

+0

@RRUZ: ¡De nada! – Remko

3

Para mí, esto funcionó, se pone el nombre de la máquina conectada.

Environment.GetEnvironmentVariable("CLIENTNAME") 
0

Si desea obtener el identificador de sesión remoto y obtener la dirección IP que conectado a través de Citrix puede utilizar el siguiente. Esto fue diseñado para ejecutarse cuando un usuario se conecta a un servidor a través de una sesión citrix y muestra/crea una cadena para la dirección IP desde la que se conecta.

// 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(); 
     } 
    } 

} 
Cuestiones relacionadas