Windows服务如何执行GUI应用程序?

我已经写了一个Windows服务,允许我远程运行和停止应用程序。 这些应用程序使用CreateProcess运行,这对我来说很有用,因为它们大多数只执行后端处理。 最近,我需要运行向当前登录用户呈现GUI的应用程序。 如何在C ++中编写代码以允许我的服务找到当前活动的桌面并在其上运行GUI?


Roger Lipscombe的回答是,使用WTSEnumerateSessions查找正确的桌面,然后使用CreateProcessAsUser在该桌面上启动应用程序(将STARTUPINFO结构的一部分作为桌面句柄传递给它)是正确的。

不过,我强烈建议不要这样做。 在一些环境中,比如终端服务器主机中有许多活跃用户,确定哪个桌面是“活动”桌面并不容易,甚至可能无法实现。

但最重要的是,如果应用程序突然出现在用户的桌面上,这很可能发生在一个糟糕的时间(或者因为用户根本没有期望它,或者因为您尝试在会话不是时启动应用程序还没有初始化,在关闭的过程中,或其他)。

更传统的方法是在全球启动组中为您的服务设置一个小型客户端应用程序的快捷方式。 此应用随后将随每个用户会话一起启动,并可用于启动其他应用(如果需要的话),而不需要任何用户凭证,会话和/或桌面的杂耍。

另外,这个快捷方式可以根据需要由管理员移动/禁用,这将使应用程序的部署更容易,因为它不会偏离其他Windows应用程序使用的标准...


简短的回答是“你不这样做”,因为打开在另一个用户环境下运行的GUI程序是一个安全漏洞,通常称为Shatter Attack。

看看这个MSDN文章:交互式服务。 它提供了一些服务与用户交互的选项。

总之你有这些选择:

  • 使用WTSSendMessage函数在用户会话中显示一个对话框。

  • 创建一个单独的隐藏的GUI应用程序,并使用CreateProcessAsUser函数在交互式用户的上下文中运行该应用程序。 设计GUI应用程序以通过进程间通信(IPC)的某种方法与服务进行通信,例如命名管道。 该服务与GUI应用程序通信以告诉它何时显示GUI。 应用程序将用户交互的结果传回服务,以便服务可以采取适当的措施。 请注意,IPC可以通过网络公开您的服务接口,除非您使用适当的访问控制列表(ACL)。

    如果此服务在多用户系统上运行,请将该应用程序添加到以下注册表项中,以便它在每个会话中运行:HKEY_LOCAL_MACHINE SOFTWARE Microsoft Windows CurrentVersion Run。 如果应用程序对IPC使用命名管道,则服务器可以根据会话ID为每个管道指定一个唯一名称,从而区分多个用户进程。


  • WTSEnumerateSessions和CreateProcessAsUser。

    链接地址: http://www.djcxy.com/p/18469.html

    上一篇: How can a Windows service execute a GUI application?

    下一篇: How do I uninstall a Windows service if the files do not exist anymore?