这个问题告诉我如何检测远程桌面会话。
有谁知道是否有可能从远程连接的初始化位置找出来?
-Vegar
由于它在Windows中,使用netstat来检查你连接的机器和哪个端口,并且只是解析出使用远程桌面使用的端口的地址。
@Vegar,您可以使用WTSEnumerateSessions和WTSQuerySessionInformation函数来检索此信息。
检查这个链接的例子使用Jedi Api头 。
检查这个代码。
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所说,使用WTSClientAddress类型的WTSQuerySessionInformation函数可以返回客户端的本地IP地址。 如果你想得到真正的ip,你可以使用位于JwaWinSta单元的WinStationGetRemoteIPAddress帮助函数。
Var Port : Word; IpAddr : WideString; Begin WinStationGetRemoteIPAddress(WTS_CURRENT_SERVER,WTS_CURRENT_SESSION,IpAddr,Port); End;
WTSQuerySessionInformation返回客户端IP作为客户端报告它,这可能是(一)它的本地IP地址。 如果您想知道连接的REAL IP地址和端口,可以使用WinStationQueryInformationW和WinStationRemoteAddress信息类。 你需要Jedi Apilib中的JwaWinsta。
我也在同一个单元中提供了一个简单的包装:
function WinStationGetRemoteIPAddress(hserver: HANDLE; SessionId: DWORD; var RemoteIPAddress: WideString; var Port: WORD): Boolean;
对我来说,这工作,它得到了连接的机器的名称。
Environment.GetEnvironmentVariable("CLIENTNAME")
尝试运行qwinsta
如果您想获得远程会话ID并获取通过Citrix连接的IP地址,则可以使用以下方法。 这被设计为当用户通过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(); } } }