C# 检测远程桌面连接
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/973802/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Detecting remote desktop connection
提问by Alan
Is there anyway, in a program, to detect if a program is being run from inside a remote desktop session or if the program is being run normal in .NET 2.0? What I'm trying to do is, I create a timeclock application which will clock a person in and out and keep track. But this particular person, I suspect, is remoting into their computer at work, from home, and clocking in and out.
无论如何,在程序中,是否可以检测程序是否正在从远程桌面会话内部运行,或者程序是否在 .NET 2.0 中正常运行?我想要做的是,我创建了一个时钟应用程序,它可以为一个人打卡进出并跟踪记录。但我怀疑这个特定的人正在工作、在家和打卡打卡时远程访问他们的计算机。
Any ideas how I can solve this issue (and taking away remote desktop access is not an option)? My idea is, if there is a way to detect remote desktop sessions, I will simply implement this into the progam and prevent them from clocking in remotely.
我有什么想法可以解决这个问题(并且取消远程桌面访问不是一种选择)?我的想法是,如果有一种方法可以检测远程桌面会话,我将简单地将其实现到程序中并防止它们远程计时。
回答by John Gietzen
http://www.appdeploy.com/messageboards/tm.asp?m=21420&mpage=1&key=厬
http://www.appdeploy.com/messageboards/tm.asp?m=21420&mpage=1&key=厬
The system variable %sessionname% will return Console if its local or RDP* if its remote.
系统变量 %sessionname% 将返回 Console(如果是本地的)或 RDP*(如果是远程的)。
isRDP = [System.Environment]
.GetEnvironmentVariable("SESSIONNAME").StartsWith("RDP-")
回答by Steven A. Lowe
allegedly,
据称,
System.Windows.Forms.SystemInformation.TerminalServerSession
will be true for a remote desktop session (or VNC session)
对于远程桌面会话(或 VNC 会话)为真
but i'd test it to be sure ;-)
但我会测试它以确保;-)
回答by Jared Harley
If you're concerned about VNC, it looks like it would be possible to check open TCP connections with netstat
. In a command prompt, type:
如果您担心 VNC,似乎可以使用netstat
. 在命令提示符中,键入:
netstat -n -a -p tcp
and check to see if the port 5900 is "ESTABLISHED". Of course, 5900 is the default connection port, so it would be dependent on what port is set.
并检查端口 5900 是否为“ESTABLISHED”。当然,5900 是默认的连接端口,所以这取决于设置的端口。
From there, I found this post at CodeGuruthat explains how to use netstat
in your c# program:
从那里,我在 CodeGuru上找到了这篇文章,解释了如何netstat
在你的 c# 程序中使用:
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, ...)
}
回答by kicsit
If you don't want to add a reference to System.Windows.Forms.dll just for this (as suggested above), then you can also call the underlying system call directly via PInvoke, like this:
如果您不想为此添加对 System.Windows.Forms.dll 的引用(如上所述),那么您也可以直接通过 PInvoke 调用底层系统调用,如下所示:
int result = GetSystemMetrics(SystemMetric.SM_REMOTESESSION);
bool isRemoteSession = (result != 0);
The SystemMetric enumeration can be found at PInvoke.net - SystemMetric(but you can just use the value of 0x1000); while the signature for GetSystemMetrics at PInvoke.net - GetSystemMetrics.
SystemMetric 枚举可以在PInvoke.net - SystemMetric上找到(但您可以只使用 0x1000 的值);而PInvoke.net - GetSystemMetrics 上的 GetSystemMetrics签名。
I tested this with RDP and VNC - works with the former (admin/console mode also), does not detect the latter.
我使用 RDP 和 VNC 对此进行了测试 - 与前者(管理员/控制台模式也)一起工作,没有检测到后者。
回答by trlkly
All remote login programs require a service or program running on the local machine. The questioner only needs to worry about VNC and its clones if those services or programs are allowed to run on his local machine. They are not necessary for Remote Desktop use, and there are Remote Desktop clients for all operating systems. A VNC server is unnecessary if Remote Desktop is working.
所有远程登录程序都需要在本地机器上运行的服务或程序。如果允许这些服务或程序在他的本地机器上运行,提问者只需担心 VNC 及其克隆。它们不是远程桌面使用所必需的,并且所有操作系统都有远程桌面客户端。如果远程桌面正在工作,则不需要 VNC 服务器。
Furthermore, the VNC clones can't log in for you unless you install them as an administrator on the server machine. As long as you don't let users run processes as other users, the only concern is if one of your other employees is logging in as the problematic one. And if that's the case, no technical solution is going to be sufficient. Even if you have individual cards for each employee that must be used to log in, the problematic employee could just give his friend the card.
此外,除非您以管理员身份在服务器计算机上安装 VNC 克隆,否则它们无法为您登录。只要您不让用户以其他用户的身份运行进程,唯一需要担心的是您的其他员工是否以有问题的员工身份登录。如果是这样的话,没有任何技术解决方案是足够的。即使您为每个员工都必须使用单独的卡片登录,问题员工也可以将卡片交给他的朋友。
回答by JhordyRosario
Well, I had a similar issue a few days ago. What I did to resolve it was took advantage of the fact that some Remote Desktop Applicationuse a known default port, at least VNCand/or Microsoft Remote Desktop Connection. So I created a method which tells if the port is being used, as follows:
好吧,几天前我遇到了类似的问题。我为解决这个问题所做的是利用了这样一个事实,即某些远程桌面应用程序使用已知的默认端口,至少是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
);
}
Remember to put the using statements with the libraries at the beginning of the file where the method is.
请记住将带有库的 using 语句放在方法所在的文件的开头。
You just have to pass for example a parameter like the 3389 portwhich is the default port for Remote Desktop Connection, or the 5900 portwhich is the default port for VNC Connections.
例如,您只需传递一个参数,例如3389 端口,它是远程桌面连接的默认端口,或5900 端口,它是VNC 连接的默认端口。
The method is created with C# 4.0features but it can perfectly be done with and older version of C#.Net or Visual Basic.
该方法是使用C# 4.0功能创建的,但它可以完美地使用旧版本的C#.Net 或 Visual Basic。
This worked for me since I only needed to check for the two application I mentioned before.
这对我有用,因为我只需要检查我之前提到的两个应用程序。
I hope it can help.
我希望它能有所帮助。
回答by Thomas Levesque
For Windows Store apps, you can use this:
对于 Windows 应用商店应用,您可以使用:
Windows.System.RemoteDesktop.InteractiveSession.IsRemote
回答by Peter
回答by PolicyWatcher
Just a note to say that using GetSystemMetrics(SystemMetric.SM_REMOTESESSION) on its own has stopped being reliable for Windows 8 / Server 2012 onwards if the session is using RemoteFX virtualisation of the GPU.
请注意,如果会话使用 GPU 的 RemoteFX 虚拟化,则单独使用 GetSystemMetrics(SystemMetric.SM_REMOTESESSION) 对于 Windows 8 / Server 2012 以后不再可靠。
The "official" method of detecting RDS is described by Microsoft here: Detecting the Remote Desktop Services environment(Last updated 31 May 18).
Microsoft 在此处描述了检测 RDS 的“官方”方法:检测远程桌面服务环境(上次更新时间为 18 年 5 月 31 日)。
It consists of using the SystemMetrics call anda registry check at
它包括使用 SystemMetrics 调用和注册表检查
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\GlassSessionId
The code samples in that article are C++ only, but given that it's just a registry lookup, I don't think folks will find it too tricksty to replicate in other languages.
那篇文章中的代码示例仅为 C++,但鉴于它只是一个注册表查找,我认为人们不会觉得用其他语言复制它太棘手。
I'd like to hope that at least some of the .Net built in functions mentioned upthread are following this in full, but :
我希望至少有一些 .Net 内置函数提到 upthread 完全遵循这一点,但是:
SystemParameters.IsRemoteSession is noted hereas "Maps to SM_REMOTESESSION. See GetSystemMetrics", and
SystemParameters.IsRemotelyControlled is noted hereas the same,
SystemParameters.IsRemoteSession在此处注明为“映射到 SM_REMOTESESSION。请参阅 GetSystemMetrics”,以及
SystemParameters.IsRemotelyControlled在这里注明是一样的,
so I'm not optimistic.
所以我并不乐观。
I'll try to do some detailed checks shortly and post the results.
我会尽快尝试做一些详细的检查并发布结果。