如何在 Windows 服务中启动 GUI 程序?

Posted

技术标签:

【中文标题】如何在 Windows 服务中启动 GUI 程序?【英文标题】:How to launch a GUI program in a Windows service? 【发布时间】:2009-06-04 03:15:49 【问题描述】:

当我以 LocalSystem 帐户运行服务时,我可以使用以下代码在当前登录帐户下启动 GUI 程序:

WTSGetActiveConsoleSessionId->WTSQueryUserToken->CreateProcessAsUser

但是,当我以个人帐户运行该服务时,GUI 程序不会显示。我可以在任务管理器中看到它。

当服务在我的个人帐户下运行时,我应该如何启动 GUI 程序?

【问题讨论】:

【参考方案1】:

John 和 jdigital 都是正确的 - 据我了解,服务通常可以具有桌面访问权限(您必须使用本地系统)或网络访问权限(您需要指定要在其下运行的帐户)。

您需要两个将您的应用拆分为两个 - 一个用于与桌面交互,另一个用于通过网络交谈。然后,这两个部分可以相互交谈,将信息传递给最终用户。

【讨论】:

我计划通过我的帐户运行该服务,以便它可以访问本地和网络资源。 “客户”将与它交谈以接收信息并控制它。但奇怪的是,就像我在下面写的那样,它生成的文件归“管理员”所有,而不是我的帐户(Vista OS)。这让我很困惑。【参考方案2】:

我相信这一切都与权限有关。

LocalSystem 有足够的权限来模拟当前用户,但您的帐户没有。

您必须想办法将权限扩展到您的服务,要么通过提示输入凭据,要么连接到作为 LocalSystem 运行的帮助服务。

(为什么要使用您的帐户而不是 LocalSystem 运行?)

我确信有更彻底的答案来处理这样做的进出,但在高层次上,我认为这就是问题所在。

【讨论】:

谢谢 John,有两个原因:1) LocalSystem 没有权限访问 Vista 中的网络共享文件夹 2) LocalSystem 服务生成的所有文件都归“管理员”所有。我想要我的个人帐户拥有的文件。【参考方案3】:

您可能在错误的窗口站或桌面上运行。看到这个Microsoft reference on Window Stations and Desktops。

【讨论】:

该服务由我的个人帐户运行,我当前已登录。我刚刚检查,程序正在运行,但没有显示。 如果您查看链接,您会发现这不是权限问题。 Microsoft 使用 Window Stations 和 Desktops 来提供不同级别的进程隔离。有一些方法可以解决这个问题,例如 SetProcessWindowStation 和 SwitchDesktop,但通常建议将应用程序分成两部分。 是的,客户端/服务器模式是我打算做的。它将解决这样的问题。但奇怪的是,虽然该服务由我的个人帐户运行,但它生成的文件归“管理员”所有,而不是我的帐户。您可以在“文件属性->详细信息->所有者”中检查此属性。它不应该归我的帐户所有吗?【参考方案4】:

我相信您尝试执行的操作可能会被视为安全漏洞。在某些情况下也不太可能起作用。我认为 jdigital 是正确的,因为它与窗口站有关,并试图访问当前用户窗口站及其桌面。当您在有多个当前窗口站的终端服务服务器下时,这会很困惑。 Microsoft 真的不希望您随心所欲,而且每次发布的 Windows 都会让您变得更难。

我认为你最好的办法是从另一个角度解决问题,只需创建一个用户运行的 GUI 应用程序(手动或登录时自动)并与你的服务对话。

【讨论】:

如果是这样,用户在关闭 GUI 应用程序时将不会收到通知。但似乎我别无选择。 :( @trudger:不。如果用户站起来离开计算机,他们也不会收到通知,但这并不意味着您随软件一起发布了手铐。 是的,这是有道理的。我已经决定使用管道在 GUI 和服务之间进行通信。也许我还可以缓冲这些事件并在用户登录时将它们显示给用户。

以上是关于如何在 Windows 服务中启动 GUI 程序?的主要内容,如果未能解决你的问题,请参考以下文章

VS CodedUI无法启动经典Windows应用程序的GUI

有啥方法可以从 Windows 7 上的 Windows 服务启动 GUI 应用程序?

从 Windows 服务启动 GUI 应用程序

如何通过SSH在远程Linux服务器上启动GUI软件?

错误1053:服务没有及时响应启动或控制请求

如何在 Windows Embedded 8 中自动启动非 Surface 应用程序?