检测远程桌面服务环境
为了优化性能,最好让应用程序检测它们是否在远程桌面服务客户端会话中运行。 例如,当应用程序在远程会话上运行时,它应消除不必要的图形效果,如 图形效果中所述。 如果用户在本地环境中运行应用程序,则应用程序无法优化其行为。
以下示例显示一个函数,如果应用程序在远程会话中运行,则返回 TRUE ;如果应用程序在控制台上运行,则返回 FALSE 。
#include <windows.h>
#pragma comment(lib, "user32.lib")
BOOL IsRemoteSession(void)
{
return GetSystemMetrics( SM_REMOTESESSION );
}
有关详细信息,请参阅 运行时链接到Wtsapi32.dll。
不应使用 GetSystemMetrics (SM_REMOTESESSION) 来确定应用程序是否在Windows 8及更高版本或Windows Server 2012远程会话中运行,而远程会话是否还可能使用对 Microsoft 远程显示协议 (RDP) RemoteFX vGPU 改进。 在这种情况下, GetSystemMetrics (SM_REMOTESESSION) 会将远程会话标识为本地会话。
应用程序可以检查以下注册表项,以确定会话是否是使用 RemoteFX vGPU 的远程会话。 如果存在本地会话,则此注册表项提供本地会话的 ID。
HKEY_LOCAL_MACHINE\System\CurrentControlSet\Control\Terminal Server\GlassSessionId
如果运行应用程序的当前会话的 ID 与注册表项中的 ID 相同,则应用程序在本地会话中运行。 以这种方式标识为远程会话的会话包括使用 RemoteFX vGPU 的远程会话。 下面的示例代码对此进行了演示。
#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;
}