24

Is there a way my program can determine when it's running on a Remote Desktop (Terminal Services)?

I'd like to enable an "inactivity timeout" on the program when it's running on a Remote Desktop session. Since users are notorious for leaving Remote Desktop sessions open, I want my program to terminate after a specified period of inactivity. But, I don't want the inactivity timeout enabled for non-RD users.

Kluge
  • 3,567
  • 3
  • 24
  • 21

3 Answers3

20

GetSystemMetrics(SM_REMOTESESSION) (as described in http://msdn.microsoft.com/en-us/library/aa380798.aspx)

Franci Penov
  • 74,861
  • 18
  • 132
  • 169
  • 1
    ```You should not use GetSystemMetrics(SM_REMOTESESSION) to determine if your application is running in a remote session in Windows 8 and later or Windows Server 2012 and later if the remote session may also be using the RemoteFX vGPU improvements to the Microsoft Remote Display Protocol (RDP)``` From https://learn.microsoft.com/en-us/windows/win32/termserv/detecting-the-terminal-services-environment . (A corner case you might have to check) – Sahil Singh Mar 01 '21 at 07:52
  • 1
    Yeah, there might have been some small changes happened in the last 12 years or so. ;-) Thanks for the comment, it's useful to know. – Franci Penov Mar 04 '21 at 17:20
14

Here's the C# managed code i use:

/// <summary>
/// Indicates if we're running in a remote desktop session.
/// If we are, then you MUST disable animations and double buffering i.e. Pay your taxes!
/// 
/// </summary>
/// <returns></returns>
public static Boolean IsRemoteSession
{
    //This is just a friendly wrapper around the built-in way
    get
    {
        return System.Windows.Forms.SystemInformation.TerminalServerSession;
    }
}
Ian Boyd
  • 246,734
  • 253
  • 869
  • 1,219
6

The following works if you want to know about YOUR application which is running in YOUR session:

BOOL IsRemoteSession(void)
{
   return GetSystemMetrics( SM_REMOTESESSION );
}

But not in general for any process ID.


If you want to know about any arbitrary process which could be running in any arbitrary session then you can use the below method.

You can first convert the process ID to a session ID by calling ProcessIdToSessionId. Once you have the session ID you can use it to call: WTSQuerySessionInformation. You can specify WTSInfoClass as value WTSIsRemoteSession and this will give you the information about if that application is a remote desktop connection or not.

BOOL IsRemoteSession(DWORD sessionID)
{
   //In case WTSIsRemoteSession is not defined for you it is value 29
   return WTSQuerySessionInformation(WTS_CURRENT_SERVER_HANDLE, sessionID, WTSIsRemoteSession, NULL, NULL);
}
Brian R. Bondy
  • 339,232
  • 124
  • 596
  • 636
  • What are the situations that can cause a process to be in a different session? Is this if i'm asking about services, or processing running under other logged in users? – Ian Boyd Aug 16 '10 at 17:56
  • When you do a new login, either from the local machine or via RDP without the /console switch, a new session is created. When a new session is created any process created will be started in that session by default. You can also target sessions when you create a process via Win32 API CreateProcessAsUser. – Brian R. Bondy Aug 16 '10 at 18:35
  • Old post, but it looks like Win32Api docs are still misleading. It states: *The WTSQuerySessionInformation function returns a value of TRUE to indicate that the current session is a remote session, and FALSE to indicate that the current session is a local session*. I tried it, at it always returns TRUE if you provide valid buffer as parameter. When called like shown above, it returns FALSE and GetLastError is 1784. – macmac Mar 26 '21 at 09:58
  • Argh... not my day for editing comments... Sample below:`BOOL IsRemoteSession() { BOOL IsRemote = FALSE; char *Buffer; DWORD BufferLen = 0; if ( WTSQuerySessionInformation( WTS_CURRENT_SERVER_HANDLE, WTS_CURRENT_SESSION, WTSIsRemoteSession, &Buffer, &BufferLen )) { IsRemote = *((BOOL*) Buffer); WTSFreeMemory((void*) Buffer); } return IsRemote; }` – macmac Mar 26 '21 at 10:07