如何编写也可以作为 winforms 程序运行的 c# 服务? [英] How to write c# service that I can also run as a winforms program?

查看:20
本文介绍了如何编写也可以作为 winforms 程序运行的 c# 服务?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个用 C# 编写的 Windows 服务,它充当一堆网络设备到后端数据库的代理.为了测试并添加一个模拟层来测试后端,我希望有一个 GUI 供测试操作员能够运行模拟.也用于作为演示发送的精简版.GUI 和服务不必同时运行.实现这种决斗操作的最佳方式是什么?

I have a windows service written in C# that acts as a proxy for a bunch of network devices to the back end database. For testing and also to add a simulation layer to test the back end I would like to have a GUI for the test operator to be able run the simulation. Also for a striped down version to send out as a demo. The GUI and service do not have to run at the same time. What is the best way to achieve this duel operation?

这是我的解决方案,结合了 这个问题我是作为服务运行吗使用 这个优秀的代码 马克·格拉维尔

Here is my solution combing stuff from this question , Am I Running as a Service and Install a .NET windows service without InstallUtil.exe using this excellent code by Marc Gravell

它使用以下行来测试是运行 gui 还是作为服务运行.

It uses the following line to test if to run the gui or run as service.

 if (arg_gui || Environment.UserInteractive || Debugger.IsAttached)

这是代码.


using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Windows.Forms;
using System.ComponentModel;
using System.ServiceProcess;
using System.Configuration.Install;
using System.Diagnostics;

namespace Form_Service
{
   static class Program
   {
      /// 
      /// The main entry point for the application.
      /// 
      [STAThread]
      static int Main(string[] args)
      {
         bool arg_install =  false;
         bool arg_uninstall = false;
         bool arg_gui = false;
         bool rethrow = false;
         try
         {
            foreach (string arg in args)
            {
               switch (arg)
               {
                  case "-i":
                  case "-install":
                     arg_install = true; break;
                  case "-u":
                  case "-uninstall":
                     arg_uninstall = true; break;
                  case "-g":
                  case "-gui":
                     arg_gui = true; break;
                  default:
                     Console.Error.WriteLine("Argument not expected: " + arg);
                     break;
               }
            }
            if (arg_uninstall)
            {
               Install(true, args);
            }
            if (arg_install)
            {
               Install(false, args);
            }
            if (!(arg_install || arg_uninstall))
            {
               if (arg_gui || Environment.UserInteractive || Debugger.IsAttached)
               {
                  Application.EnableVisualStyles();
                  Application.SetCompatibleTextRenderingDefault(false);
                  Application.Run(new Form1());
               }
               else
               {
                  rethrow = true; // so that windows sees error... 
                  ServiceBase[] services = { new Service1() };
                  ServiceBase.Run(services);
                  rethrow = false;
               }
            }
            return 0;
         }
         catch (Exception ex)
         {
            if (rethrow) throw;
            Console.Error.WriteLine(ex.Message);
            return -1;
         }
      }

      static void Install(bool undo, string[] args)
      {
         try
         {
            Console.WriteLine(undo ? "uninstalling" : "installing");
            using (AssemblyInstaller inst = new AssemblyInstaller(typeof(Program).Assembly, args))
            {
               IDictionary state = new Hashtable();
               inst.UseNewContext = true;
               try
               {
                  if (undo)
                  {
                     inst.Uninstall(state);
                  }
                  else
                  {
                     inst.Install(state);
                     inst.Commit(state);
                  }
               }
               catch
               {
                  try
                  {
                     inst.Rollback(state);
                  }
                  catch { }
                  throw;
               }
            }
         }
         catch (Exception ex)
         {
            Console.Error.WriteLine(ex.Message);
         }
      }
   }

   [RunInstaller(true)]
   public sealed class MyServiceInstallerProcess : ServiceProcessInstaller
   {
      public MyServiceInstallerProcess()
      {
         this.Account = ServiceAccount.NetworkService;
      }
   }

   [RunInstaller(true)]
   public sealed class MyServiceInstaller : ServiceInstaller
   {
      public MyServiceInstaller()
      {
         this.Description = "My Service";
         this.DisplayName = "My Service";
         this.ServiceName = "My Service";
         this.StartType = System.ServiceProcess.ServiceStartMode.Manual;
      }
   }

}

推荐答案

你基本上有两个选择.在服务上公开 API,然后您可以从 UI 应用程序调用该 API,或者使服务能够作为 winforms 应用程序或服务运行.

You basically have two choices. Either expose an API on the service which you can then call from the UI app OR enable the service to run either as a winforms app or a service.

第一个选项非常简单 - 使用远程处理或 WCF 来公开 API.

The first option is pretty easy - use remoting or WCF to expose the API.

第二个选项可以通过将您的应用程序的胆量"移动到一个单独的类中,然后创建一个服务包装器和一个 win-forms 包装器来实现,它们都调用您的胆量"类.

The second option can be achieved by moving the "guts" of your app into a separate class then create a service wrapper and a win-forms wrapper that both call into your "guts" class.

static void Main(string[] args)
{
    Guts guts = new Guts();

    if (runWinForms)
    {
        System.Windows.Forms.Application.EnableVisualStyles();
        System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(false);

        FormWrapper fw = new FormWrapper(guts);

        System.Windows.Forms.Application.Run(fw);
    }
    else
    {
        ServiceBase[] ServicesToRun;
        ServicesToRun = new ServiceBase[] { new ServiceWrapper(guts) };
        ServiceBase.Run(ServicesToRun);
    }
}

这篇关于如何编写也可以作为 winforms 程序运行的 c# 服务?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆