【问题标题】:how to run(F5) windows service from visual studio如何从 Visual Studio 运行(F5)Windows 服务
【发布时间】:2011-01-16 08:30:16
【问题描述】:

如何从 Visual Studio 运行 Windows 服务项目。

我正在 Visual Studio 2008 中构建 Windows 服务,我必须始终从控制面板运行服务,然后将调试器附加到正在运行的服务实例。这有点烦人,因为我正在清理大量代码并且在开发过程中需要多次重启我的服务。

我想设置我的项目以便能够按 F5 并运行服务并直接进入调试模式。关于如何实现这一点的一些提示会很棒。

提前致谢!!!

【问题讨论】:

标签: visual-studio unit-testing debugging testing windows-services


【解决方案1】:

复制自here

static void Main(string[] args)  
{  
    DemoService service = new DemoService();  

    if (Environment.UserInteractive)  
    {  
        service.OnStart(args);  
        Console.WriteLine("Press any key to stop program");  
        Console.Read();  
        service.OnStop();  
    }  
    else 
    {  
        ServiceBase.Run(service);  
    }  
}  

这应该允许您在 Visual Studio 中运行。

另一种方法是通过调用System.Diagnostics.Debugger.Break() 在代码中嵌入程序断点。当您将其放入服务的 OnStart() 回调并从服务控制台启动服务时,程序断点将触发一个对话框,允许您附加到现有的 Visual Studio 实例或启动新的实例。这实际上是我用来调试服务的机制。

【讨论】:

  • 仅供参考,在 Windows 8 中,他们似乎对 Windows 服务进行了一些更改,并大大降低了他们执行交互操作的能力。 Debugger.Launch() 和 Debugger.Break() 似乎不再触发允许您选择和 IDE 进行调试的 GUI 对话框,因此服务只是挂起。仅供参考
  • 几点注意事项: 1- 由于 OnStart 和 OnStop 是受保护的方法,并且从外部类调用,因此添加一个公共 DoStart 和 DoStop 来完成实际工作。 2- 如果项目类型保持为 Windows 应用程序,Console.Read 将抛出异常,因此将项目类型更改为控制台应用程序。
  • 我有一项从 XML 文件获取安装配置的服务,我想在安装前对其进行验证。我想调试该过程,那么在使用 Visual Studio 安装之前如何调试服务。我正在使用 VS2019
  • @hackerbuddy 看看这是否有帮助。 stackoverflow.com/questions/4525450/…
【解决方案2】:

在您的Main() 例程中检查Debugger.IsAttached,如果它是真的启动您的应用程序,就好像它是一个控制台,如果不是,调用ServiceBase.Run()

【讨论】:

    【解决方案3】:

    可以为作为控制台应用程序运行的 Windows 服务设置一个配套项目,但使用反射访问服务方法。有关详细信息和示例,请参见此处:http://ryan.kohn.ca/articles/how-to-debug-a-windows-service-in-csharp-using-reflection/

    这是您在控制台应用程序中需要的相关代码:

    using System;
    using System.Reflection;
    
    namespace TestableWindowsService
    {
      class TestProgram
      {
        static void Main()
        {
          Service1 service = new Service1();
    
          Type service1Type = typeof (Service1);
    
          MethodInfo onStart = service1Type.GetMethod("OnStart", BindingFlags.NonPublic | BindingFlags.Instance); //retrieve the OnStart method so it can be called from here
    
          onStart.Invoke(service, new object[] {null}); //call the OnStart method
        }
      }
    }
    

    【讨论】:

      【解决方案4】:

      你也可以这样做:(参见 cmets 的解释)

      public class Program : ServiceBase
      {
          private ServiceHost _serviceHost = null;
          public Program()
          {
              ServiceName = "";
          }
          /// <summary>
          /// The main entry point for the application.
          /// </summary>
          static void Main()
          {
                      #if(!DEBUG)
                     // when deployed(built on release Configuration) to machine as windows service use this
                        ServiceBase[] ServicesToRun;
                        ServicesToRun = new ServiceBase[]  {  new Program() };
                        ServiceBase.Run(ServicesToRun);
                      #else
                     // when debugging use this (When debugging after building in Debug Configuration)
                     //If you want the DEBUG preprocessor constant in Release you will have to check it on in the project configuration
                      Program progsvc = new Program();
                      progsvc.OnStart(new string[] { });
                      System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
                      #endif                        
          }
          protected override void OnStart(string[] args)
          {
                      // Start Web Service
                      if (_serviceHost != null)
                      {
                          _serviceHost.Close();
                      }
                      _serviceHost = new ServiceHost(typeof(Namespace.Service));
                      _serviceHost.Open();
          }       
      }
      

      【讨论】:

        【解决方案5】:

        创建一个单独的项目,它只引用服务项目并实例化和启动服务。它就像一个普通的应用程序一样运行,你可以进入它。

        YourService s = new YourService();
        s.Start();
        

        【讨论】:

          【解决方案6】:

          只需从服务构造函数中调用 OnStart() 事件

          我是通过以下方式做到的

              public XXX()
              {
                  InitializeComponent();
                  OnStart(new string[] { "shafi", "moshy" });
              }
          

          【讨论】:

            【解决方案7】:

            你想把你的windows服务当作一个shell,里面应该有很少的代码,所以你不必测试它。

            你应该在课堂上拥有你希望你的服务做的每一件事。

            您可以对您的类进行单元测试,如果它有效,则将其引用到您的服务中。

            这样,当你让课堂做你想做的每一件事时,当它应用于你的服务时,每一件事都应该起作用。 :)

            您是否可以通过事件日志查看服务在运行时正在执行的操作,这也是一种很好的测试方式:D 试试看。

            namespace WindowsService
            {
                public partial class MyService : ServiceBase
                {
                    public MyEmailService()
                    {
                        InitializeComponent();
                        if (!System.Diagnostics.EventLog.SourceExists("MySource")) // Log every event
                        {
                            System.Diagnostics.EventLog.CreateEventSource(
                                "MySource", "MyNewLog"); // Create event source can view in Server explorer
                        }
                        eventLogEmail.Source = "MySource";
                        eventLogEmail.Log = "MyNewLog";  
            
                        clsRetriveEmail Emails = new clsRetriveEmail();
                        eventLogEmail.WriteEntry("Populateing database with mail"); // log event
                        Emails.EmailGetList(); // Call class
                    }
                    protected override void OnStart(string[] args)
                    {
                        eventLogEmail.WriteEntry("Started");
                    }
                    protected override void OnStop()
                    {
                        eventLogEmail.WriteEntry("Stopped");
                    }
                    protected override void OnContinue()
                    {    
                        eventLogEmail.WriteEntry("Continuing");
                    }
                    }
                }
            

            【讨论】:

              【解决方案8】:

              这些链接在使用服务时非常有用。

              这是创建它们的过程 http://msdn.microsoft.com/en-us/library/zt39148a.aspx

              James Michael Hare 在他的博客http://geekswithblogs.net/BlackRabbitCoder/ 上写了他制作的一个非常好的模板/框架,使开发(和调试)Windows 服务变得更加容易:C# 工具箱:可调试、自安装的 Windows 服务模板(1 of 2) http://geekswithblogs.net/BlackRabbitCoder/archive/2010/09/23/c-windows-services-1-of-2-creating-a-debuggable-windows.aspx

              它为您提供了快速入门所需的所有基础知识。最重要的是,它为您提供了一种非常好的方式来调试您的服务,就好像它是一个常规的控制台应用程序一样。我还可以提到它提供了开箱即用的功能来安装(和卸载)您的服务。这篇文章的第二部分可以在这个链接中找到。

              我自己用过几次,真的可以推荐它。

              【讨论】:

                猜你喜欢
                • 1970-01-01
                • 1970-01-01
                • 2013-09-09
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                相关资源
                最近更新 更多