2

我想枚举给定进程的子窗口以检查对话框窗口。由于我不会进入这里的原因,如果它发现任何,我想随后杀死该应用程序。

运行独立应用程序来执行此操作没有任何问题。该应用程序可以访问(通过一些 P/Invoke 调用)进程的窗口,然后我可以终止该应用程序。

但是,将相同的代码作为服务运行并不能按预期工作。运行该服务的用户似乎无法与桌面交互(这是我只能看到 LOCAL 系统帐户的设置)。

有谁知道任何解决方法?我可以从 Windows 服务枚举进程的窗口吗?

仅供参考 - 我正在使用的代码(至少是改编版)可在此处获得:https ://stackoverflow.com/a/1405088/2115261

4

3 回答 3

3

您可能正在运行 Windows 7(或 8 或 Vista),因为 Windows Servcies 与桌面交互的能力最后在 Windows XP 中得到支持。

MSDN 上有一份白皮书,描述了对 Vista 及更高版本所做的更改。基本上,现在不可能以任何方式与桌面交互。

但是,CodeProject 上有一个示例演示了如何从 Windows 服务与 Task Scheduler 交互,并且 Task Scheduler 执行的进程可以与桌面交互。也许这对您来说是一个合适的解决方法。

于 2013-05-22T14:59:57.637 回答
1

您只能在与您的进程相同的终端服务会话(也称为远程桌面会话)上枚举窗口。但是,如果有适当的权限,您可以在另一个终端服务会话中启动子进程来代表您完成工作,但您需要了解潜在的安全问题,具体取决于您如何执行此操作。

假设您已经获得了目标进程的句柄,最简单的方法是使用OpenProcessToken在目标会话中获取令牌、DuplicateTokenEx复制它并CreateProcessAsUser启动子进程。由于您只需要一个是/否的答案,因此您可以使用进程退出代码而不需要 IPC 机制。

安全隐患:由于您的子进程在用户的上下文中运行,因此知识渊博的用户可能会阻止它正常运行。此外,如果您确实使用 IPC 机制,则必须将来自子进程的输入视为不受信任(检查缓冲区溢出等)。

另一种方法是在您自己的上下文中但在目标会话中启动子流程。IIRC,您可以通过复制自己的令牌并SetTokenInformation在副本上使用来更改TokenSessionId,然后再使用CreateProcessAsUser.

安全隐患:子进程,以及通过它的服务进程和服务帐户,可能会受到破坏攻击(恶意窗口消息)和其他风险,尽管完整性级别机制可能会在一定程度上缓解这种情况。据我了解,创建单独的窗口站和桌面(使用适当的 ACL)可以消除这些风险,但我不确定对您要运行的代码的影响。另一种缓解措施是CreateRestrictedToken在启动子进程之前从令牌中删除所有组和权限。

除非绝对必要用户不能破坏您检测对话框窗口存在的能力,否则我强烈推荐第一种方法。

于 2013-05-23T22:42:26.530 回答
0

如果您为服务提供本地系统帐户以登录,您将能够在服务属性中勾选“允许服务与桌面交互”复选框(来自服务控制管理器)。

请参阅服务属性页的“登录”选项卡。

这可能对你有用。但不幸的是,它可能不会。仍然值得快速尝试吗?

于 2013-05-22T14:57:52.623 回答