这里有一个简单的问题让我抓狂。
我有一个用 C# 编写的 Windows 服务,它应该可以在 XP、Vista 和 7 上运行,并且能够枚举当前用户桌面(如果有)的窗口以进行监视。
到目前为止:
我使用 EnumDesktopWindows
将 IntPtr.Zero
作为 hdesktop
参数传递,因为我没有用户桌面的句柄,这只会导致在枚举分配给服务(Session0\Winsta0)的特殊桌面中存在的少数窗口
我试过EnumWindows
,结果和上面一样!
我尝试使用 GetThreadDesktop
API 获取已知进程的桌面,传递 explorer.exe 线程之一的 ID 但它返回 0,所以我无法获取它的桌面或任何其他线程。
我尝试使用 OpenInputDesktop
获取输入桌面,这显然返回了 session0 内的桌面,而不是用户的桌面。
我能做什么?!
如果您好奇的话,我正在编写一个信息亭应用程序,它需要监视所有窗口并防止危险的窗口,例如任务管理器、Internet 选项、Cmd,以及通常用户不应打开的任何内容。
欢迎提出任何建议。 :)
最佳答案
您不能毫无异常(exception)地枚举另一个 session 中的窗口。另一方面,如果您具有“作为操作系统的一部分”(SeTcbPrivilege
) 权限,则可以在另一个 session 中创建进程。
参见 Launching a process in user’s session from a service了解如何做到这一点。
您最终可以得到两个进程,一个作为 NT 服务运行的 Controller ,以及在用户 session 中运行的代理。这两个进程可以通过命名管道进行通信,如果被用户杀死, Controller 将重新启动代理。
但是,您还应该使用组策略或其他配置来锁定客户端,以防止其他窗口首先打开。具体来说,Software Restriction Policies将允许您阻止未列入白名单的可执行文件运行。
如果您使用的是 Windows 8.1,您还可以使用新推出的 Kiosk Mode .
关于c# - 在另一个 session 中枚举用户桌面的 Windows,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22232646/