c# - 在另一个 session 中枚举用户桌面的 Windows

标签 c# windows winapi

这里有一个简单的问题让我抓狂。

我有一个用 C# 编写的 Windows 服务,它应该可以在 XP、Vista 和 7 上运行,并且能够枚举当前用户桌面(如果有)的窗口以进行监视。

到目前为止:

我使用 EnumDesktopWindowsIntPtr.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/

相关文章:

c# - 在实现中设置私有(private) Setter 的模拟 void 方法

c# - 如何制作循环而不是 switch 语句?

c++ - 如何在 C++ 中维护对 COM 对象的弱引用?

c++ - WinAPI _Interlocked* char 的内部函数,short

c++ - Windows服务安装返回错误1053

c# - UnhandledException 在 Windows Phone 上的所有情况下都能正常工作吗?

c# - 在数据库中存储和解析 bool 表达式

mysql - Raspi2 Win 10 物联网 C# + MySql

Windows wget不下载文件但在浏览器中下载

php - 如何从 PHP 调用 Win32 API?