1

首先,我知道一些制作真正交互式 Windows 服务的正确方法。

情况是,我确实有一个与用户交互的工具。但是,它确实 通过弹出窗口和 Windows 通知区域(又名系统托盘)显示非阻塞通知。它还写入它显示的通知的日志文件。

此工具通常由主用户应用程序生成,只要主应用程序是普通应用程序,这些通知就会按预期工作。

当此工具由 Windows 服务生成时,自然不会显示任何通知。(服务的桌面会话不可见。)但这没关系,我们有日志文件,这些通知只是 - 通知,用户在任何情况下都必须看到的任何内容。

现在的问题变成了:在服务(服务本身或它启动的任何进程)的上下文中运行的进程是否“允许”进行显示可见 GUI 的 Windows API 调用?

  • 大多数 Windows API 调用(例如创建和显示窗口、使用Shell_NotifyIcon等)在服务的不可见会话中是否表现相同?
  • 或者我是否必须确保在整个源代码中,在服务的上下文中没有调用 GUI 显示/修改内容?

是的,调用::MessageBox是个坏主意,因为它会阻塞。但我可以处理这些电话。

是的,这可以设计得更好,但这是我目前所拥有的,如果我不必将整个工具拆开以确保服务中没有运行与 GUI 相关的代码,那就太好了。

4

2 回答 2

2

来自 Windows 服务的 GUI 元素显示在 Session 0 上。在 Windows XP 和 2003 上,用户可以登录到 Session 0 并与服务创建的窗口正常交互,但微软在交互服务的核心中插了一把刀通过隔离 Session 0 来实现Vista(及更高版本)。

因此,要回答您的具体问题:

在服务(服务本身或它启动的任何进程)的上下文中运行的进程是否“允许”进行显示可见 GUI 的 Windows API 调用?大多数 Windows API 调用(例如,创建和显示窗口、使用 Shell_NotifyIcon 等)在服务的不可见会话中的行为是否相同?

是的,GUI 调用是允许的,并且应该正常成功。我知道的唯一值得注意的例外是与托盘图标相关的例外,因为提供任务栏(explorer.exe)的进程没有在隔离的会话 0 中运行。

或者我是否必须确保在整个源代码中,在服务的上下文中没有调用 GUI 显示/修改内容?

这应该不是必需的,尽管您应该谨慎地处理来自服务的任何 GUI 交互。彻底测试!

于 2013-06-28T19:26:53.707 回答
0

我想提供一些信息。Raymonds Chen 对另一个答案的评论

您应该避免在服务中显示 UI,因为您可能会触发 UI 检测服务,这会将用户暂时切换到您的服务 UI。– 雷蒙德陈

我发现这些好文章:

哪里可以找到关于UI 检测服务 ( UI0Detect) 是什么、做什么以及它应该如何工作的解释。

交互式服务检测(任务栏上的闪烁按钮)是针对旧应用程序的一种缓解措施,可检测服务是否正在尝试与桌面交互。这由交互式服务检测 (UI0Detect) 服务处理。

但是,必须注意,这只有在尝试查看 GUI 的服务设置了“允许服务与桌面交互”标志时才有效,因为只有这样服务进程才会运行WinSta0Session0甚至允许它显示任何内容一点也不。

Alex Ionescu 提到了这一点:

如果 UI0Detect.exe ... SCM 已根据 Window Hook DLL 的请求启动它。服务将继续...服务首先进行一些验证以确保它在正确的WinSta0\Default windowsstation 和桌面上运行,然后通知 SCM 成功或失败。

所以,回到 Raymond 的评论:据我所知,只要服务没有勾选该type= interact选项(请参阅 sc.exe),并且通常您不勾选此选项, UI0Detect 服务就不会这样做任何东西,不应该有任何触发它的“危险”。


注意:以上信息基于我在一台 Windows 7 PC 上的有限研究和测试。

于 2013-07-01T08:33:28.583 回答