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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/308135/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-15 11:38:18  来源:igfitidea点击:

How can I enumerate the open windows (~EnumWindows) of another user session

windowswinapi

提问by Gaspar Nagy

I have an application that can list the opened windows of the current session. It uses the EnumWindows method from the user32.dll.

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

I would like to run this code from a windows service, but as the service is not attached to a user session, it returns nothing obviously.

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

So the question is, how can I enumerate the open windows of another user session (e.g. with a specific logon user)?

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

Similarly to EnumWindows, I also would like to get the foreground window of the user session as well (like GetForegroundWindow works for the current user).

与 EnumWindows 类似,我也想获取用户会话的前台窗口(就像 GetForegroundWindow 适用于当前用户)。

采纳答案by DavidK

As far as I'm aware, you can't access the windows of one session from another. It's also worth noting that there's not really any such thing as "the current session" - there may be multiple users logged on through terminal services, or XP's fast user switching.

据我所知,您无法从另一个会话访问一个会话的窗口。还值得注意的是,实际上并没有“当前会话”之类的东西——可能有多个用户通过终端服务登录,或者 XP 的快速用户切换。

One approach to this would be to add a program to each user's profile with no UI that just communicates with your service. You'd still have to cope with the fact that there could be multiple active sessions, though.

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

回答by csgero

According to this documentyou can create a process in an other user's logon session using CreateProcessAsUser, and could enumerate the windows there. You will still need some IPC mechanism to communicate with the service.

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

回答by Brian R. Bondy

The accepted answer is not correct.

接受的答案不正确。

So the question is, how can I enumerate the open windows of another user session?

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

You can enumerate the open windows of any session if you're running as a service running as the local System account.

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

To do this first enumerate the sessions with WTSEnumerateSessions. Then enumerate the window stations inside each session with EnumWindowStations. Then enumerate the desktops for each Window Station with EnumDesktops. Finally you an enumerate the Windows in those Desktops with EnumWindows.

为此,首先使用WTSEnumerateSessions枚举会话。然后使用EnumWindowStation枚举每个会话中的窗口站。然后使用EnumDesktops枚举每个 Window Station 的桌面。最后,您可以使用EnumWindows枚举这些桌面中的 Windows 。

(e.g. with a specific logon user)

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

There can be many concurrent logged on users via Terminal services or fast user switching.

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

Similarly to EnumWindows, I also would like to get the foreground window of the user session as well (like GetForegroundWindow works for the current user).

与 EnumWindows 类似,我也想获取用户会话的前台窗口(就像 GetForegroundWindow 适用于当前用户)。

This can be done by launching an app with a found user token in the Session, Window Station, and Desktop. From there you can call any Win32 API like GetForegroundWindow and report the info back to your parent process.

这可以通过在会话、Window Station 和桌面中使用找到的用户令牌启动应用程序来完成。从那里您可以调用任何 Win32 API,例如 GetForegroundWindow 并将信息报告回您的父进程。

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

您可以在此处了解有关会话、窗口站和桌面如何工作的更多信息