Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/309.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 检测远程桌面连接的源_C#_Windows_Delphi_Remote Desktop_Terminal Services - Fatal编程技术网

C# 检测远程桌面连接的源

C# 检测远程桌面连接的源,c#,windows,delphi,remote-desktop,terminal-services,C#,Windows,Delphi,Remote Desktop,Terminal Services,告诉我如何检测远程桌面会话 有人知道远程连接是从哪里初始化的吗?因为它在windows中,所以使用netstat检查您连接到的机器和端口,并解析出使用远程桌面使用的端口的机器的地址。@Vegar,您可以使用和函数检索此信息 检查此项以获取使用的示例 检查此代码 program ProjectTsInfo; {$APPTYPE CONSOLE} Uses Windows, JwaWinType, JwaWtsApi32, JwaWinsock2, SysUtils, T

告诉我如何检测远程桌面会话


有人知道远程连接是从哪里初始化的吗?

因为它在windows中,所以使用netstat检查您连接到的机器和端口,并解析出使用远程桌面使用的端口的机器的地址。

@Vegar,您可以使用和函数检索此信息

检查此项以获取使用的示例

检查此代码

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.

尝试运行

WTSQuerySessionInformation在客户端报告时返回客户端IP,这可能是它的本地IP地址之一。如果您想知道实际的ip地址和连接的端口,可以使用WinStationQueryInformationW和信息类WinStationRemoteAddress。 你需要绝地武士阿皮利布的JwaWinsta

我在同一单元中也提供了一个简单的包装器:

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

对我来说,这起作用了,它得到了连接的机器的名称

Environment.GetEnvironmentVariable("CLIENTNAME")

如果您想获取远程会话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();
        }
    }

}

而且,由于远程桌面始终使用端口3389,这将正常工作。谢谢这仅在您有一个远程连接的情况下有效,否则您无法看到哪个会话连接到哪个远程计算机。
netstat
的输出是否受当前区域设置的影响?这会使字符串解析变得更加复杂。与依赖外部程序和可变输出格式的解决方案相比,更喜欢API解决方案。是的,我同意这是一个令人讨厌的解决方案,但它是一个快速的解决方案。远程桌面并不总是使用端口3389,这可以由用户定义,并且通常是为了安全,如果不使用vpn,甚至有必要使用
WTSEnumeratessions
?我认为对会话ID使用
wts\u Current\u Session
就足够了ProcessIdToSessionId@Rob你说得对,WTSEnumerateSessions函数用于获取所有会话的信息,我发布了一个使用wts_Current_会话和WTSEnumerateSessions的示例。;)我现在正在尝试WinStationGetRemoteIPaddress()。我在家,办公室电脑上有一个RDC。当我调用此方法时,它返回路由器的ip地址,而不是本地机器的ip地址。顺便说一句,在这种情况下,netstat返回WORKGROUP。不太有用…@Vegar:是的,当然有用,你可以使用外部ip进行连接,在大多数情况下,外部ip是路由器或调制解调器拥有的ip。WinStationGetRemoteIPAddress返回终端服务器报告的IP地址,它将匹配服务器上netstat的输出。+1@Remko您是对的WTSClientAddress可以报告本地IP而不是真实IP。我更新我的答案。p、 s:非常感谢您在绝地Api标题中所做的出色工作
// 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();
        }
    }

}