答案 0 :(得分: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.
<强>更新强>
正如@Remko所说,具有 WTSClientAddress 类型的 WTSQuerySessionInformation 函数可以返回客户端的本地IP。如果你想获得真正的IP,你可以使用位于JwaWinSta单元的WinStationGetRemoteIPAddress助手函数。
Var
Port : Word;
IpAddr : WideString;
Begin
WinStationGetRemoteIPAddress(WTS_CURRENT_SERVER,WTS_CURRENT_SESSION,IpAddr,Port);
End;
答案 1 :(得分:4)
因为它在Windows中使用netstat来检查您连接到哪台机器以及哪些端口,并且只解析使用远程桌面使用的端口的地址。
答案 2 :(得分:4)
WTSQuerySessionInformation在客户端报告它时返回客户端IP,这可能是其中一个本地IP地址。如果您想知道连接的REAL IP地址和端口,可以使用WinStationQueryInformationW和信息类WinStationRemoteAddress。 你需要Jedi Apilib的JwaWinsta单位。
我在同一单元中提供了一个简单的包装器:
function WinStationGetRemoteIPAddress(hServer: HANDLE; SessionId: DWORD;
var RemoteIPAddress: WideString; var Port: WORD): Boolean;
答案 3 :(得分:4)
对我来说,这很有效,它得到了连接机器的名称。
Environment.GetEnvironmentVariable("CLIENTNAME")
答案 4 :(得分:1)
尝试运行qwinsta
答案 5 :(得分:0)
如果您想获取远程会话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();
}
}
}