【问题标题】:How can I create a Windows application that can run with a GUI *or* as a Windows service in C#?如何创建一个可以使用 GUI *或 * 作为 C# 中的 Windows 服务运行的 Windows 应用程序?
【发布时间】:2009-02-20 00:49:04
【问题描述】:

我想使用 C# 创建一个应用程序...:

  • 可以作为 Windows 应用程序运行,带有 GUI(它将指示进度、状态等)

  • 可以作为 Windows 服务运行,无需 GUI

有可能吗?有人可以帮我入门吗?

我想另一种选择是我可以创建一个 Windows 服务,然后创建一个单独的 GUI 应用程序,该应用程序可以轮询 Windows 服务以从中获取数据(进度、状态等)。

在这种情况下...如何从我的 GUI 应用程序中的 Windows 服务获取数据?

【问题讨论】:

    标签: c# windows-services


    【解决方案1】:

    我正在做与您要求的类似的事情。我已经对其进行了编程,因此如果您将命令行参数“/form”发送到可执行文件,它将弹出一个 windows 窗体而不是作为服务运行。

    就运行后台作业本身而言,在这两种情况下,您都需要执行某种线程(可能使用计时器)来完成工作并将状态异步报告回您的表单。这将是一个关于创建线程 GUI 应用程序的完全不同的讨论主题。

    “表单或服务”代码如下所示:

    static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static void Main(string[] args)
        {
            if (args.Length > 0 && args[0] == "/form")
            {
                var form = new MainForm();
                Application.Run(form);
                return;
            }
    
            var ServicesToRun = new ServiceBase[]
                {
                    new BackgroundService()
                };
    
            ServiceBase.Run(ServicesToRun);
        }
    }
    

    【讨论】:

      【解决方案2】:

      我从未做过可以作为 Windows 服务或 GUI 运行的应用程序,但我们有很多应用程序,您可以使用编译器标志在控制台应用程序和 Windows 服务之间切换。 (我刚刚看到了 cmd 行 arg 的答案 - 这可能会更好!)

      然后我们通常只使用编译器标志在两者之间切换。这是一个例子……我没有完全考虑清楚,但它可能会给你一个开始:

      #define RUN_AS_SERVICE
      
      using System;
      using System.Collections.Generic;
      using System.Linq;
      using System.Windows.Forms;
      using System.ServiceProcess;
      
      namespace WindowsFormsApplication1
      {
          static class Program
          {
              /// <summary>
              /// The main entry point for the application.
              /// </summary>
              [STAThread]
              static void Main()
              {
      #if RUN_AS_SERVICE
      
                  System.ServiceProcess.ServiceBase[] ServicesToRun;
                  ServicesToRun = new System.ServiceProcess.ServiceBase[]
                  {
                      new MyService()
                  };
                  System.ServiceProcess.ServiceBase.Run(ServicesToRun);
      #else
                  // Run as GUI
                  Application.EnableVisualStyles();
                  Application.SetCompatibleTextRenderingDefault(false);
                  Application.Run(new Form1());
      #endif
              }
          }
          public class MyService : ServiceBase
          {
              protected override void OnStart(string[] args)
              {
                  // Start your service
              }
      
              protected override void OnStop()
              {
                  // Stop your service
              }
          }
      }
      

      【讨论】:

        【解决方案3】:

        在库中构建实际应用程序。然后,您可以添加任何您想要的 UI(我松散地说,因为服务并不是真正的 UI)。只要您将应用程序视为一个 Windows 应用程序和一个服务应用程序,您就是在开发两个应用程序。如果您将应用程序视为它解决的业务问题,那么您会想到 Windows 窗体 UI 和服务 UI,这更符合您的需求。

        虽然这听起来很合理,但您会惊讶于有多少应用程序需要完全覆盖才能变成不同的 UI 类型。感谢你的提问。它让我相信我正在写的这本书是有必要的。 :-)

        【讨论】:

          【解决方案4】:

          您应该选择后一个选项。创建您的服务,然后创建一个单独的 GUI 应用程序。框架中已经为您提供了完成所有这些工作的大部分管道。看看 ServiceController 类。

          【讨论】:

          • 这个选项听起来是迄今为止最有希望的......但我需要做的不仅仅是停止、启动和暂停服务。我需要能够发送特定于服务的命令以使其执行其他操作,并发送命令以从服务中检索数据... ServiceController 可以这样做吗?
          • +1 这可能是 imo 最好的主意。就我而言,我的服务的所有设置都存储在一个 xml 文档中。我的服务都在计时器上运行,每次事件触发时,它都会检查设置文件。
          【解决方案5】:

          我看到了这个帖子,它可能会为您提供更多信息

          How to write c# service that I can also run as a winforms program?

          【讨论】:

            猜你喜欢
            • 2010-09-08
            • 1970-01-01
            • 2010-10-04
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2016-12-31
            • 1970-01-01
            相关资源
            最近更新 更多