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

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

问题描述

我已经写在充当到后端数据库一堆网络设备的代理C#中的窗口服务。为了测试还增加一个模拟层测试后端我想有一个GUI的测试操作人员能够运行模拟。也为条纹下来的版本送出去作为演示。 GUI和服务不必在同一时间运行。什么是实现这一对决操作的最佳方式。



编辑:
这里是我的解决方案,从的这个问题是我作为服务运行安装.NET Windows服务,而不InstallUtil.exe 使用的 Gravell


$ b $这个优秀的代码 b

它使用以下行测试,如果运行GU​​I或运行的服务。

 如果(arg_gui || Environment.UserInteractive || Debugger.IsAttached)

下面是代码。

  
使用系统; System.Collections中使用
;
使用System.Collections.Generic;
使用System.Linq的;使用System.Windows.Forms的
;
使用System.ComponentModel;
使用System.ServiceProcess;
使用System.Configuration.Install;使用System.Diagnostics程序
;

命名空间Form_Service
{
静态类节目
{
///
///的主入口点应用程序。
///
[STAThread]
静态INT主要(字串[] args)
{
布尔arg_install = FALSE;
布尔arg_uninstall = FALSE;
布尔arg_gui = FALSE;
布尔重新抛出= FALSE;

{
的foreach(在args串ARG)
{
开关(ARG)
{
案-i:
案-install:
arg_install = TRUE;打破;
案-u:
案-uninstall:
arg_uninstall = TRUE;打破;
案-g:
案-gui:
arg_gui = TRUE;打破;
默认:
Console.Error.WriteLine(预计不会论据:+ ARG);
中断;
}
}
如果(arg_uninstall)
{
安装(真实的,参数);
}
如果(arg_install)
{
安装(假,参数);
}
如果(!(arg_install || arg_uninstall))
{
如果(arg_gui || Environment.UserInteractive || Debugger.IsAttached)
{
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(假);
Application.Run(新Form1中());
}
,否则
{
再次抛出= TRUE; //使Windows能够看到错误...
ServiceBase [] =服务{新服务1()};
ServiceBase.Run(服务);
再次抛出= FALSE;
}
}
返回0;
}
赶上(异常前)
{
如果(重新抛出)抛出;
Console.Error.WriteLine(ex.Message);
返回-1;
}
}

静态无效的安装(布尔撤消,字串[] args)
{

{
控制台.WriteLine(撤消卸载:安装);使用(AssemblyInstaller研究所=新AssemblyInstaller(typeof运算(程序).Assembly,参数))

{
IDictionary的状态=新的Hashtable();
inst.UseNewContext = TRUE;

{
如果(撤销)
{
inst.Uninstall(州);
}
,否则
{
inst.Install(州);
inst.Commit(州);
}
}

{

{
inst.Rollback(州);
}
赶上{}
扔;
}
}
}
赶上(异常前)
{
Console.Error.WriteLine(ex.Message);
}
}
}

[runInstaller的(真)]
公共密封类MyServiceInstallerProcess:ServiceProcessInstaller
{
公共MyServiceInstallerProcess ()
{
this.Account = ServiceAccount.NetworkService;
}
}

[runInstaller的(真)]
公共密封类MyServiceInstaller:的ServiceInstaller
{
公共MyServiceInstaller()
{
this.Description =我的服务;
this.DisplayName =我的服务;
this.ServiceName =我的服务;
this.StartType = System.ServiceProcess.ServiceStartMode.Manual;
}
}

}


解决方案

您基本上有两种选择。无论是暴露在服务的API,然后你可以从用户界面应用程序调用或启用服务运行无论是作为一个WinForms应用程序或服务。



第一个选项是很简单 - 使用远程处理或WCF揭露API



第二个选项可以通过移动你的应用程序的胆量到一个单独的类,然后创建一个服务实现包装和双赢的形式包装,都调用到您的胆级。

 静态无效的主要(字串[] args) 
{
胆量胆量=新的胆量();

如果(runWinForms)
{
System.Windows.Forms.Application.EnableVisualStyles();
System.Windows.Forms.Application.SetCompatibleTextRenderingDefault(假);

FormWrapper FW =新FormWrapper(胆);

System.Windows.Forms.Application.Run(FW);
}
,否则
{
ServiceBase [] ServicesToRun;
ServicesToRun =新ServiceBase [] {新ServiceWrapper(胆量)};
ServiceBase.Run(ServicesToRun);
}
}


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?

Edit: 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

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

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

Here is the code.


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;
      }
   }

}

解决方案

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.

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

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);
    }
}

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

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