Detección del entorno de Servicios de Escritorio remoto

Para optimizar el rendimiento, se recomienda que las aplicaciones detecten si se ejecutan en una sesión de cliente de Servicios de Escritorio remoto. Por ejemplo, cuando una aplicación se ejecuta en una sesión remota, debe eliminar efectos gráficos innecesarios, como se describe en Efectos gráficos. Si el usuario ejecuta la aplicación en un entorno local, no es tan fundamental para que la aplicación optimice su comportamiento.

En el ejemplo siguiente se muestra una función que devuelve TRUE si la aplicación se ejecuta en una sesión remota y FALSE si la aplicación se ejecuta en la consola.

#include <windows.h>
#pragma comment(lib, "user32.lib")

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

Para obtener más información, vea Vinculación en tiempo de ejecución a Wtsapi32.dll.

No debe usar GetSystemMetrics(SM_REMOTESESSION) para determinar si la aplicación se ejecuta en una sesión remota en Windows 8 y versiones posteriores o Windows Server 2012 y versiones posteriores si la sesión remota también puede usar las mejoras de RemoteFX vGPU en el Protocolo de visualización remota de Microsoft (RDP). En este caso, GetSystemMetrics(SM_REMOTESESSION) identificará la sesión remota como una sesión local.

La aplicación puede comprobar la siguiente clave del Registro para determinar si la sesión es una sesión remota que usa vGPU de RemoteFX. Si existe una sesión local, esta clave del Registro proporciona el identificador de la sesión local.

HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\GlassSessionId

Si el identificador de la sesión actual en la que se ejecuta la aplicación es el mismo que en la clave del Registro, la aplicación se ejecuta en una sesión local. Las sesiones identificadas como sesión remota de esta manera incluyen sesiones remotas que usan RemoteFX vGPU. En el siguiente ejemplo de código se muestra este caso.

#define TERMINAL_SERVER_KEY _T("SYSTEM\\CurrentControlSet\\Control\\Terminal Server\\")
#define GLASS_SESSION_ID    _T("GlassSessionId")

BOOL
IsCurrentSessionRemoteable()
{
    BOOL fIsRemoteable = FALSE;
                                       
    if (GetSystemMetrics(SM_REMOTESESSION)) 
    {
        fIsRemoteable = TRUE;
    }
    else
    {
        HKEY hRegKey = NULL;
        LONG lResult;

        lResult = RegOpenKeyEx(
            HKEY_LOCAL_MACHINE,
            TERMINAL_SERVER_KEY,
            0, // ulOptions
            KEY_READ,
            &hRegKey
            );

        if (lResult == ERROR_SUCCESS)
        {
            DWORD dwGlassSessionId;
            DWORD cbGlassSessionId = sizeof(dwGlassSessionId);
            DWORD dwType;

            lResult = RegQueryValueEx(
                hRegKey,
                GLASS_SESSION_ID,
                NULL, // lpReserved
                &dwType,
                (BYTE*) &dwGlassSessionId,
                &cbGlassSessionId
                );

            if (lResult == ERROR_SUCCESS)
            {
                DWORD dwCurrentSessionId;

                if (ProcessIdToSessionId(GetCurrentProcessId(), &dwCurrentSessionId))
                {
                    fIsRemoteable = (dwCurrentSessionId != dwGlassSessionId);
                }
            }
        }

        if (hRegKey)
        {
            RegCloseKey(hRegKey);
        }
    }

    return fIsRemoteable;
}