Detecting remote desktop connection

C#.Netvb.net

C# Problem Overview


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.

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.

C# Solutions


Solution 1 - C#

allegedly,

System.Windows.Forms.SystemInformation.TerminalServerSession

will be true for a remote desktop session (or VNC session)

but i'd test it to be sure ;-)

Solution 2 - C#

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:

    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.

I tested this with RDP and VNC - works with the former (admin/console mode also), does not detect the latter.

Solution 3 - C#

For Windows Store apps, you can use this:

Windows.System.RemoteDesktop.InteractiveSession.IsRemote

Solution 4 - C#

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

The system variable %sessionname% will return Console if its local or RDP* if its remote.

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

Solution 5 - C#

For WPF applications there is System.Windows.SystemParameters.IsRemoteSession and System.Windows.SystemParameters.IsRemotelyControlled.

Solution 6 - C#

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 Application use a known default port, at least VNC and/or Microsoft Remote Desktop Connection. So I created a method which tells if the port is being used, as follows:

/* 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.

You just have to pass for example a parameter like the 3389 port which is the default port for Remote Desktop Connection, or the 5900 port which is the default port for VNC Connections.

The method is created with C# 4.0 features but it can perfectly be done with and older version of C#.Net or Visual Basic.

This worked for me since I only needed to check for the two application I mentioned before.

I hope it can help.

Solution 7 - C#

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.

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.

Solution 8 - C#

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.

The "official" method of detecting RDS is described by Microsoft here: Detecting the Remote Desktop Services environment (Last updated 31 May 18).

It consists of using the SystemMetrics call and a registry check at

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.

I'd like to hope that at least some of the .Net built in functions mentioned upthread are following this in full, but :

  • SystemParameters.IsRemoteSession is noted here as "Maps to SM_REMOTESESSION. See GetSystemMetrics", and

  • SystemParameters.IsRemotelyControlled is noted here as the same,

so I'm not optimistic.

I'll try to do some detailed checks shortly and post the results.

Solution 9 - C#

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:

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.

From there, I found this post at CodeGuru that explains how to use netstat in your c# program:

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, ...)
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionAlanView Question on Stackoverflow
Solution 1 - C#Steven A. LoweView Answer on Stackoverflow
Solution 2 - C#kicsitView Answer on Stackoverflow
Solution 3 - C#Thomas LevesqueView Answer on Stackoverflow
Solution 4 - C#John GietzenView Answer on Stackoverflow
Solution 5 - C#PeterView Answer on Stackoverflow
Solution 6 - C#JhordyRosarioView Answer on Stackoverflow
Solution 7 - C#trlklyView Answer on Stackoverflow
Solution 8 - C#PolicyWatcherView Answer on Stackoverflow
Solution 9 - C#Jared HarleyView Answer on Stackoverflow