Windows vista OpenInputDesktop()用于确定安全/登录桌面 Visual C++ 2008

Windows vista OpenInputDesktop()用于确定安全/登录桌面 Visual C++ 2008 ,windows-vista,window,desktop,enumeration,Windows Vista,Window,Desktop,Enumeration,如何确定当前交互用户是否在锁定的桌面(Windows键L)或关机屏幕(Vista或7)上等待程序在注销期间关闭 HDESK hd=OpenInputDesktop(0,false,读取控制) 这对于默认桌面上的用户应用程序很好,但在锁定或关闭桌面时失败,错误代码为5,据我所知,原因是用户没有打开安全桌面对象的权限 从系统帐户下运行的服务调用此函数将返回错误1(函数无效)。我相信该服务在任何情况下都处于错误的会话(会话0)中,并且无法确定任何其他会话的交互式桌面 我有一个应用程序在当前交互用户下运

如何确定当前交互用户是否在锁定的桌面(Windows键L)或关机屏幕(Vista或7)上等待程序在注销期间关闭

HDESK hd=OpenInputDesktop(0,false,读取控制)

这对于默认桌面上的用户应用程序很好,但在锁定或关闭桌面时失败,错误代码为5,据我所知,原因是用户没有打开安全桌面对象的权限

从系统帐户下运行的服务调用此函数将返回错误1(函数无效)。我相信该服务在任何情况下都处于错误的会话(会话0)中,并且无法确定任何其他会话的交互式桌面

我有一个应用程序在当前交互用户下运行,而且系统服务也在运行,因此可以从任何一个用户处执行代码

我是否应该尝试列举所有会话、窗口站和桌面


即使如此,如果只能在会话0中从系统服务调用OpenInputDesktop,如何确定当前的交互式桌面?

我认为您可以尝试以下方法:

  • 从当前交互用户中运行的进程:
    使用
    WTSRegisterSessionNotification
    注册会话更改通知。一旦注册,交互进程将获得登录/注销通知。更多信息可在此处找到:
    http://msdn.microsoft.com/en-us/library/aa383841.aspx
    http://blogs.msdn.com/b/oldnewthing/archive/2006/01/04/509194.aspx

  • 来自服务(在会话0中运行):
    • 使用
      GetProcessWindowsStation
      获取当前站点的服务句柄,并将其保存以供以后使用
    • 使用
      WTSGetActiveConsoleSessionId
      获取当前交互式会话的会话id
    • 使用
      WTSQuerySessionInformation
      WTSWinStationName
      info类获取与当前会话id对应的站点名称
    • 使用
      OpenWindowStation
      打开此站点。使用
      setProcessWindowsStation
      将此工作站设置为您的服务进程
    • 现在,您可以使用
      OpenInputDesktop
      检查用户是否已登录
    • 通过调用
      CloseWindowStation
      关闭打开的交互式窗口站。通过调用
      setProcessWindowsStation
      ,在先前保存了站点句柄的情况下,重置服务的原始窗口站点
注:目前,
“WinSta0”
是Windows中唯一的交互式工作站。因此,您可以跳过
WTSGetActiveConsoleSessionId
WTSQuerySessionInformation
调用。

注意: MSDN关于
WTSQuerySessionInformation
WTSWinStationName

注意:尽管名称不同,指定此类型不会返回窗口桩号名称。而是返回远程桌面服务会话的名称。每个远程桌面服务会话都与一个交互式窗口站相关联。目前,由于交互式窗口站唯一支持的窗口站名称是“WinSta0”,因此每个会话都与自己的“WinSta0”窗口站相关联。有关详细信息,请参见窗口桩号


也许答案是以某种方式监控用户何时切换台式机?这可能吗?我认为第二种方法不能正常工作。会话0中运行的服务将无法通过SetProcessWindowsStation()将会话1中的winsta0设置为我自己。因为SetProcessWindowsStation()上的窗口站必须与当前会话相关联。