在 Windows Server 2003 中,如何检查我的程序是否在本地控制台(“在服务器计算机的屏幕上”)而不是远程会话中运行?
我使用的是 Delphi Win32,所以任何基于 Windows API 的方法都应该可以工作。
会话编号不会告诉您吗?
ProcessIdToSessionId (GetCurrentProcessId(),&dwSessionNum)
您还必须使用 GetVersionEx 检查操作系统版本:对于直到 XP/Server 2003 会话 0 的所有内容都是本地的(服务或交互式控制台),任何更高版本的都是虚拟的。对于 Vista/2008 会话 0 和 1 都是本地的(0 是服务,1 是控制台),其他一切都是虚拟的。
我猜你的 Delphi 单元会将会话号声明为 var,所以你不需要 & 符号。
WTSGetActiveConsoleSessionId()应该返回附加到控制台的会话 ID。然后,您可以将该会话 ID 与应用程序的当前会话 ID 进行比较,以确定您是否在控制台上运行。Vista(不确定 Windows Server 2008)不一定会给控制台会话 ID 1(快速用户切换,有人吗?)。
对我来说,ProcessIdToSessionId 在直接在物理控制台上运行和登录到管理会话 (mstsc /admin) 时都返回 0。
但是,当您通过 RDP 登录时,Windows(在这种情况下为 XP Pro)会创建一个新会话,该会话会显示在物理控制台上,该控制台仅显示“此计算机已锁定”。WTSGetActiveConsoleSessionId 返回第二个会话的会话 ID,在我的例子中是 2。
因此,即使您的应用程序在控制台上运行,现在也有两个控制台会话,并且您的应用程序没有在活动会话上运行。在我的代码中,我将会话 ID 与 0 进行比较。
布赖恩是正确的,尽管没有使用快速用户切换,但我后来遇到了 Vista 报告交互式控制台的会话 id 为 2。当然,这可能只是一个错误:-)