【问题标题】:Detecting remote desktop connection检测远程桌面连接
【发布时间】:2026-01-04 11:55:01
【问题描述】:

无论如何,在程序中是否有检测程序是从远程桌面会话内部运行还是在 .NET 2.0 中正常运行?我正在尝试做的是,我创建了一个时钟应用程序,它将一个人进出并保持跟踪。但我怀疑,这个特定的人正在工作中远程连接到他们的计算机,从家里,并打卡进出。

有什么想法可以解决这个问题(并且不能取消远程桌面访问)?我的想法是,如果有办法检测远程桌面会话,我将简单地将其实现到程序中并防止它们远程打卡。

【问题讨论】:

  • 哈哈,这是一个有趣的问题:)
  • 这里的一个问题将是不同远程工具的范围 - MSTSC 和 VNC 将是大竞争者,但是 PCAnywhere、Live Mesh、GoToMyPC 等呢,更不用说 Live Meeting 和 Adob​​e Connect Pro 之类的东西了,两者都可以进行桌面远程处理。要稳健地做到这一点,这可能非常困难。
  • 很抱歉问...我知道这超出了主题。但是使用 RDP 通过不同网络连接的客户端到客户端是否通用?

标签: c# .net vb.net


【解决方案1】:

据称,

System.Windows.Forms.SystemInformation.TerminalServerSession

适用于远程桌面会话(或 VNC 会话)

但我会对其进行测试以确保 ;-)

【讨论】:

  • 我非常怀疑这会启动 VNC 会话。它可能会检测到 RDP。
  • 我已经检查过了,并且(与 %sessionname% - 其他答案不同)即使使用 /console 或 /admin 开关也可以正常工作。这听起来像是 MSTSC 的最佳答案。
  • 良好的 VNC 服务器插入图形驱动程序以提高性能。有可能检测到这一点。
  • 适用于 Windows 远程桌面。
  • @MarkRichman 你需要参考 Windows.Forms 但它应该可以工作
【解决方案2】:

如果您不想为此添加对 System.Windows.Forms.dll 的引用(如上所述),那么您也可以直接通过 PInvoke 调用底层系统调用,如下所示:

    int result = GetSystemMetrics(SystemMetric.SM_REMOTESESSION);
    bool isRemoteSession = (result != 0);

SystemMetric 枚举可以在PInvoke.net - SystemMetric 找到(但您可以只使用 0x1000 的值);而 GetSystemMetrics 的签名位于 PInvoke.net - GetSystemMetrics

我使用 RDP 和 VNC 对此进行了测试 - 适用于前者(也适用于管理员/控制台模式),但未检测到后者。

【讨论】:

    【解决方案3】:

    对于 Windows 应用商店应用,您可以使用:

    Windows.System.RemoteDesktop.InteractiveSession.IsRemote
    

    【讨论】:

    • 也适用于通用 Windows 平台 (UWP) 应用程序。谢谢!
    【解决方案4】:

    http://www.appdeploy.com/messageboards/tm.asp?m=21420&mpage=1&key=&#21420

    系统变量 %sessionname% 如果是本地则返回 Console,如果是远程则返回 RDP*。

    isRDP = [System.Environment]
        .GetEnvironmentVariable("SESSIONNAME").StartsWith("RDP-")
    

    【讨论】:

    • 如果您使用 /console 开关(或 /admin,取决于版本)进行 RDP,那么它会返回“Console”(我刚刚检查过;-p)
    • System.Environment..GetEnvironmentVariable("SESSIONNAME").StartsWith("RDP-");为我工作。
    • 它为我返回 RDP 上的控制台。
    【解决方案5】:

    对于 WPF 应用程序there is System.Windows.SystemParameters.IsRemoteSessionandSystem.Windows.SystemParameters.IsRemotelyControlled.

    【讨论】:

      【解决方案6】:

      好吧,几天前我遇到了类似的问题。我为解决这个问题所做的工作是利用一些 远程桌面应用程序 使用已知的默认端口,至少 VNC 和/或Microsoft 远程桌面连接。所以我创建了一个方法来判断端口是否被使用,如下:

      /* Libraries needed */
      using System.Linq;
      using System.Net.NetworkInformation;
      
      /*....
        ....
        ....*/
      
      private static bool IsPortBeingUsed(int port)
      {
          return IPGlobalProperties.GetIPGlobalProperties().
                      GetActiveTcpConnections().
                          Any(
                                  tcpConnectionInformation => 
                                  tcpConnectionInformation.LocalEndPoint.Port == port
                             );
      }
      

      记得将 using 语句和库放在方法所在文件的开头。

      您只需传递一个参数,例如 3389 端口,它是 远程桌面连接 的默认端口,或 5900 端口 这是 VNC 连接 的默认端口。

      该方法是使用 C# 4.0 功能创建的,但可以使用旧版本的 C#.Net 或 Visual Basic 完美完成。

      这对我有用,因为我只需要检查我之前提到的两个应用程序。

      希望对你有帮助。

      【讨论】:

        【解决方案7】:

        所有远程登录程序都需要在本地计算机上运行的服务或程序。如果允许这些服务或程序在他的本地机器上运行,提问者只需要担心 VNC 及其克隆。它们不是远程桌面使用所必需的,并且所有操作系统都有远程桌面客户端。如果远程桌面正在运行,则不需要 VNC 服务器。

        此外,VNC 克隆无法为您登录,除非您在服务器计算机上以管理员身份安装它们。只要您不让用户以其他用户身份运行进程,唯一需要担心的是您的其他员工是否以有问题的员工身份登录。如果是这样的话,没有任何技术解决方案是足够的。即使您为每个员工都有单独的卡必须用于登录,有问题的员工也可以只给他的朋友这张卡。

        【讨论】:

          【解决方案8】:

          请注意,如果会话使用 GPU 的 RemoteFX 虚拟化,则单独使用 GetSystemMetrics(SystemMetric.SM_REMOTESESSION) 已不再可靠用于 Windows 8 / Server 2012。

          微软在此处描述了检测 RDS 的“官方”方法:Detecting the Remote Desktop Services environment(最后更新于 18 年 5 月 31 日)。

          它包括使用 SystemMetrics 调用

          处的注册表检查
          HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\GlassSessionId
          

          那篇文章中的代码示例仅是 C++,但鉴于它只是一个注册表查找,我认为人们不会觉得它太难用其他语言复制。

          我希望至少有一些提到的 .Net 内置函数完全遵循这一点,但是:

          • SystemParameters.IsRemoteSession 是 noted here 为“映射到 SM_REMOTESESSION。请参阅 GetSystemMetrics”,并且

          • SystemParameters.IsRemotelyControlled 与noted here 一样,

          所以我并不乐观。

          我会尽快做一些详细的检查并发布结果。

          【讨论】:

          【解决方案9】:

          如果您担心 VNC,看起来可以使用netstat 检查打开的 TCP 连接。在命令提示符下,键入:

          netstat -n -a -p tcp
          

          并检查端口 5900 是否“已建立”。当然,5900是默认的连接端口,所以要看设置的端口。

          从那里,我找到了 this post at CodeGuru,它解释了如何在您的 c# 程序中使用 netstat

          string sCommand = "netstat";
          string sArgs = "";
          System.Diagnostics.ProcessStartInfo psi = new System.Diagnostics.ProcessStartInfo (sCommand, sArgs);
          
          psi.UseShellExecute = false;
          psi.RedirectStandartOutput = true;
          
          System.Diagnostics.Process proc = null;
          proc = System.Diagnostics.Process.Start(psi);
          proc.WaitForExit();
          
          // Read the first 4 lines. They don't contain any information we need to get
          for (int i = 0; i < 4; i++)
              proc.StandardOutput.ReadLine();
          
          while (true)
          {
              string strLine = proc.StandardOutput.ReadLine();
              if (strLine == null)
                  break;
          
              // Analyze the line 
              // Line is in following structure:
              // Protocol (TCP/UDP)   Local Address(host:port) Foreign Address(host:port) State(ESTABLISHED, ...)
          }
          

          【讨论】:

          • 一个小提示:看起来在 CodeGuru 上发布的代码 sn-p 有一点拼写错误,因为 StandardOutput 拼写错误为 StandartOutput
          最近更新 更多