【问题标题】:How can I run a Windows GUI application on as a service?如何将 Windows GUI 应用程序作为服务运行?
【发布时间】:2026-01-13 06:30:01
【问题描述】:

我有一个应该作为服务实现的现有 GUI 应用程序。基本上,我需要能够远程登录和注销 Windows 2003 服务器,并且仍然保持该程序运行。

这可能吗?

编辑:这里进一步完善...我没有来源,这不是我的应用程序。

【问题讨论】:

  • 这里进一步细化...我没有来源,这不是我的应用程序。
  • 这是系统管理员每天必须解决的问题,所以请询问系统管理员。由于您没有源代码,因此这不是编程问题。

标签: windows user-interface windows-services legacy


【解决方案1】:

Windows 服务不能有 GUI,因此您需要摆脱 GUI 或将您的应用程序分成两部分 - 一个没有 UI 的服务和一个“控制器”应用程序。如果您有源代码,将非 GUI 代码转换为服务很容易 - Visual Studio 有一个“Windows 服务”项目类型可以为您处理包装,并且有一个简单的演练向您展示如何创建一个负责安装的部署项目。

如果您选择第二条路线并且需要将一些原始 GUI 代码放入控制器中,则控制器和服务可以通过 WCF、.NET Remoting 或使用您自己定义的协议的普通套接字连接进行通信。如果您使用 Remoting,请务必使用“块状”接口,以尽可能少的方法调用来传输数据 - 每个调用都有相当多的开销。

如果 UI 相当简单,您也许可以不使用配置文件作为输入和日志文件,或者使用 Windows 事件日志作为输出。

【讨论】:

  • 这就是为什么它是一个棘手的问题。我有一个需要作为服务运行的现有 GUI 应用程序(无源)。
  • 这是错误的。 Windows 服务可以有 GUI。这是能够显示窗口的打印机服务的情况。
  • @labilbe - Windows 服务绝对有可能产生具有 GUI 的进程。这可能是打印机服务正在做的事情。这与具有 GUI 的服务进程本身不同。确实,Windows 操作系统的某些部分有时可以做一些不允许的事情。
  • Is what I read here on MSDN 准确吗? Vista之后没有互动服务?或者有“history changed again”,就像 Skeet 幽默地将它用于另一个话题一样。总而言之:“从 Windows Vista 开始,服务无法直接与用户交互。因此,标题为使用交互服务的部分中提到的技术不应在新代码中使用。
  • Microsoft 正试图将设备驱动程序排除在 GUI 之外。如果在服务 -> 属性下选择了“登录 -> 允许服务与桌面交互”,设备驱动程序仍然可以运行 GUI。您会看到一个弹出窗口,然后您可以在奇怪的 session 0 桌面中查看并与之交互。微软正试图扼杀这种行为。他们会成功吗?大概。他们完全杀死了它吗?不是今天。
【解决方案2】:

有没有人使用过第三方产品,例如:Always Up

似乎可以满足我的需要。这是在我需要的登录/注销周期中继续运行的能力。并且能够忽略它是一个 GUI 应用程序并运行它。

他们必须手动链接到 exe 并调用 WinMain 或其他东西。

【讨论】:

  • 我尝试过 AlwaysUp,但效果不太好,至少对于命令行应用程序而言 - 我一直收到有关“此计算机上运行的程序正在尝试显示消息”的通知.我现在改用winsw。
【解决方案3】:

您可以将其封装到 srvany,尽管您可能需要为其分配一个实际的用户帐户(而不是 LocalService 或类似的帐户)

【讨论】:

    【解决方案4】:

    您真的需要它作为服务运行,还是只需要它在未连接时保持运行?如果是后者,您可以断开连接而不是注销,应用程序将继续运行。该选项应该在选择关闭后的下拉列表中,或者您可以调用 tsdiscon.exe。

    【讨论】:

      【解决方案5】:

      我对@9​​87654321@ 有很好的体验。我能够很容易地将我的批处理文件转换为使用它的服务。

      根据this answer,我也将它用于 nginx。

      【讨论】:

        【解决方案6】:

        你有资源吗?在许多情况下,独立应用程序和服务之间的差异很小。

        大部分更改与将代码正确挂钩到服务管理器有关。完成后,您就会知道出现的任何问题都是您的程序造成的,而不是任何其他程序造成的。

        【讨论】:

          【解决方案7】:

          如果您创建服务会发生什么。该服务被配置为与桌面交互。将其配置为运行某个用户并自动启动。来自此其他应用程序上的服务 CreateProcess。我想这很快就可以尝试使用 C#(如果我记得的话,C/C++ 有很多代码甚至可以成为一项服务)。这样行吗?

          但是!

          我的第一个想法是在服务器级虚拟主机(如 Virtual Server、HyperV、VMWare)中创建虚拟计算机。这些虚拟机将作为服务运行(或 Hyper V 所做的任何事情)。虚拟机将始终运行 - 无论登录和退出。

          让这台虚拟计算机自动登录到 Windows(TweakUI 可以设置),然后使用 Startup 文件夹的快捷方式启动 GUI 应用程序。您甚至可以使用程序的 GUI 远程桌面进入它(我敢打赌 Always Up 做不到)。

          【讨论】:

            【解决方案8】:

            你可以使用ServiceMill来实现这个操作。 基本上,您在服务器上安装 ServiceMill Server。 然后单击可执行文件上的右键并单击“作为 ServiceMill 服务安装”。 接下来配置一些东西(用户/密码,如果您想与桌面交互或者如果您希望隐藏 ui...并将启动模式设置为自动)。

            Active+ Software 的另一个工具可以是解决方案,ServiceMill Exe Builder,它允许您从命令行创建服务,如果您使用持续集成服务器或者如果您计划将组件作为服务分发而无需考虑服务集成(而且它是免费的)。

            【讨论】:

              【解决方案9】:

              FireDaemonPro 将大多数 GUI 应用程序转变为服务;它不是免费的,但值得购买。

              【讨论】:

                【解决方案10】:

                首先我要问为什么你的服务需要一个用户界面。很可能它没有,但您可能需要一个从该服务获取数据的客户端。服务通常没有 GUI 的原因是它们可能没有要在其中运行的窗口环境。服务可以在没有用户登录到机器的情况下启动和运行。在这种情况下,将没有桌面供服务 GUI 运行。

                话虽如此,您可以按照 Mark 的建议将服务的属性设置为以用户身份运行。您还可以在服务的属性中指定“允许服务与桌面交互”。仅当您知道用户将登录时才执行此操作。

                【讨论】:

                  【解决方案11】:

                  服务不应该有 GUI,因为它应该在不需要用户任何干预的情况下运行,并且存在与找到正确的用户桌面并与之通信相关的各种问题。

                  既然问这个问题的原因大概是为了能够远程监控应用程序,那么这样做的方法就是拥有两个应用程序。服务端(基本上作为控制台应用程序编写)和客户端/监控 GUI 端。该服务将使用一些远程连接(当我这样做时,我使用命名管道)与客户端/监控应用程序进行通信。一个应该能够在没有另一个的情况下运行,当然服务应该能够在没有客户端的情况下运行。

                  【讨论】:

                    最近更新 更多