2010-03-17 17 views

risposta

4

Dal momento che è in finestre usano netstat per verificare che le macchine si è connessi e sulla quale le porte e basta analizzare fuori l'indirizzo per chi utilizza la porta che utilizza desktop remoto.

+0

E poiché il desktop remoto utilizza sempre la porta 3389, funzionerà. Grazie! – Vegar

+2

Funziona solo se si dispone di una singola connessione remota, altrimenti non è possibile vedere quali sessioni si connettono a quale macchina remota. –

+1

L'output di 'netstat' è influenzato dalle impostazioni locali correnti? Questo può rendere l'analisi delle stringhe * molto * più complicata. Preferisci una soluzione API su una che si basa su programmi esterni e formati di output variabili. –

9

@Vegar, è possibile utilizzare le funzioni WTSEnumerateSessions e WTSQuerySessionInformation per recuperare queste informazioni.

controllare questo link per un esempio utilizzando Jedi Api Headers.

controllare questo codice.

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

Come dice @Remko, la funzione WTSQuerySessionInformation con il tipo WTSClientAddress, può restituire l'IP locale del client. se vuoi ottenere l'ip reale puoi usare la funzione helper WinStationGetRemoteIPAddress che si trova nell'unità JwaWinSta.

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

È anche necessario utilizzare 'WTSEnumerateSessions'? Penso che usare 'wts_Current_Session' per l'ID di sessione sia sufficiente. –

+0

Per ottenere la propria sessione, utilizzare ProcessIdToSessionId –

+0

@Rob hai ragione la funzione WTSEnumerateSessions è ottenere le informazioni per tutte le sessioni, ho pubblicato un esempio utilizzando wts_Current_Session e WTSEnumerateSessions. ;) – RRUZ

4

WTSQuerySessionInformation restituisce il client IP del client segnala che, questo sarà probabilmente (uno) del suo indirizzo IP locale. Se si desidera conoscere l'indirizzo IP reale e la porta connessa, è possibile utilizzare WinStationQueryInformationW con la classe di informazioni WinStationRemoteAddress. Avrai bisogno della mia unità JwaWinsta dal Jedi Apilib.

Ho fornito un semplice involucro nella stessa unità così:

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

+1 @Remko hai ragione il WTSClientAddress in grado di segnalare l'ip locale invece dell'ip reale. aggiorno la mia risposta. p.s: grazie mille per il tuo grande lavoro negli header Jedi Api. ;) – RRUZ

+0

@RRUZ: Prego! – Remko

3

Per me, questo ha funzionato, si ottiene il nome della macchina collegata.

Environment.GetEnvironmentVariable("CLIENTNAME") 
0

Se si desidera ottenere l'ID sessione remoto e ottenere l'indirizzo IP collegato tramite Citrix è possibile utilizzare il seguente. Questo è stato progettato per essere eseguito quando un utente si connette a un server tramite una sessione di citrix e visualizza/crea una stringa per l'indirizzo IP da cui si connette.

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

} 
Problemi correlati