如何枚举另一个用户会话的打开窗口(~EnumWindows)

时间:2008-11-21 07:40:29

标签: windows winapi

我有一个应用程序可以列出当前会话的打开窗口。它使用user32.dll中的EnumWindows方法。

我想从Windows服务运行此代码,但由于该服务未附加到用户会话,因此它不会返回任何内容。

所以问题是,我如何枚举另一个用户会话的打开窗口(例如,使用特定的登录用户)?

与EnumWindows类似,我也希望获得用户会话的前台窗口(如GetForegroundWindow适用于当前用户)。

3 个答案:

答案 0 :(得分:5)

据我所知,您无法从另一个会话中访问一个会话的窗口。还值得注意的是,“当前会话”并不存在任何此类事情 - 可能有多个用户通过终端服务登录,或者XP的快速用户切换。

一种方法是向每个用户的个人资料添加一个程序,而没有只与您的服务通信的UI。但是,您仍然必须应对可能存在多个活动会话的事实。

答案 1 :(得分:5)

根据this document,您可以使用CreateProcessAsUser在其他用户的登录会话中创建一个进程,并可以枚举那里的窗口。您仍然需要一些IPC机制来与服务进行通信。

答案 2 :(得分:4)

接受的答案不正确。

  

所以问题是,如何枚举另一个用户会话的打开窗口?

如果您作为以本地系统帐户运行的服务运行,则可以枚举任何会话的打开窗口。

要执行此操作,请先使用WTSEnumerateSessions枚举会话。然后使用EnumWindowStations枚举每个会话中的窗口站。然后使用EnumDesktops枚举每个Window Station的桌面。最后,您使用EnumWindows枚举这些桌面中的Windows。

  

(例如,使用特定的登录用户)

通过终端服务或快速用户切换可以有许多并发登录用户。

  

与EnumWindows类似,我也希望获得用户会话的前台窗口(如GetForegroundWindow适用于当前用户)。

这可以通过在Session,Window Station和Desktop中启动具有找到的用户令牌的应用程序来完成。从那里你可以调用任何Win32 API,如GetForegroundWindow,并将信息报告回你的父进程。

You can learn more about how Sessions, Window Stations, and Desktops work here