2010-03-17 14 views

Antwort

4

Da es in Windows netstat verwenden, um zu überprüfen, welche Maschinen Sie sind mit und auf welchen Ports und einfach die Adresse analysieren, für die eine, die den Port verwendet, die Remote-Desktop verwendet.

+0

Und da Remote-Desktop immer Port 3389 verwendet, wird dies funktionieren. Vielen Dank! – Vegar

+2

Dies funktioniert nur, wenn Sie eine einzige Remote-Verbindung haben. Andernfalls können Sie nicht sehen, welche Sitzungen mit welchem ​​Remote-Computer verbunden sind. –

+1

Ist die Ausgabe von 'netstat' vom aktuellen Gebietsschema betroffen? Das kann das String-Parsing * viel * komplizierter machen. Bevorzugen Sie eine API-Lösung gegenüber einer, die auf externen Programmen und variablen Ausgabeformaten beruht. –

9

@Vegar, Sie können die Funktionen WTSEnumerateSessions und WTSQuerySessionInformation verwenden, um diese Informationen abzurufen.

überprüfen Sie diese link für ein Beispiel mit der Jedi Api Headers.

überprüfen Sie diesen Code.

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

Wie @Remko sagt, die WTSQuerySessionInformation Funktion mit dem WTSClientAddress Typ kann die lokale IP-Adresse des Clients zurück. Wenn Sie die echte IP-Adresse erhalten möchten, können Sie die WinStationGetRemoteIPAddress-Hilfsfunktion verwenden, die sich in der JwaWinSta-Einheit befindet.

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

Ist es sogar notwendig, 'WTSEnumerateSessions' zu verwenden? Ich denke, die Verwendung von 'wts_Current_Session' für die Sitzungs-ID wäre ausreichend. –

+0

Um Ihre eigene Sitzung zu bekommen, verwenden Sie ProcessIdToSessionId –

+0

@Rob Sie haben Recht die WTSEnumerateSessions Funktion ist es, die Informationen für alle Sitzungen zu erhalten, ich postete ein Beispiel mit Wts_Current_Session und WTSEnumerateSessions. ;) – RRUZ

4

WTSQuerySessionInformation gibt die Client-IP läuft wie der Kunde es meldet, wird dies wahrscheinlich sein (eine) davon lokale IP-Adresse ist. Wenn Sie die REAL-IP-Adresse und den verbundenen Port wissen möchten, können Sie WinStationQueryInformationW mit der Informationsklasse WinStationRemoteAddress verwenden. Sie benötigen meine Einheit JwaWinsta von der Jedi Apilib.

Ich habe eine einfache Wrapper in derselben Einheit wie auch zur Verfügung gestellt:

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

+1 @Remko Sie haben Recht, die WTSClientAddress kann die lokale IP anstelle der realen IP melden. Ich aktualisiere meine Antwort. PS: Vielen Dank für die tolle Arbeit in den Jedi Api Headers. ;) – RRUZ

+0

@RRUZ: Gern geschehen! – Remko

3

Für mich ist dies gearbeitet, es wird den Namen der Maschine verbunden.

Environment.GetEnvironmentVariable("CLIENTNAME") 
0

Wenn Sie die Remote-Sitzungs-ID abrufen und die IP-Adresse abrufen möchten, die über Citrix angeschlossen wurde, können Sie die folgende Tabelle verwenden. Dies wurde ausgeführt, wenn ein Benutzer über eine Citrix-Sitzung eine Verbindung zu einem Server herstellt und eine Zeichenfolge für die IP-Adresse anzeigt oder erstellt, von der aus eine Verbindung hergestellt wird.

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

}