如何从 Visual Studio 运行(F5)Windows 服务

问题描述 投票:0回答:9

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

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

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

提前致谢!

visual-studio unit-testing debugging testing windows-services
9个回答
33
投票

这里复制。

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 的现有实例或启动新的实例。实例。这实际上是我用来调试服务的机制。


6
投票

在您的

Main()
例程中检查
Debugger.IsAttached
,如果为真,则像控制台一样启动您的应用程序,如果不是,请调用
ServiceBase.Run()


6
投票

可以为作为控制台应用程序运行的 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
    }
  }
}

3
投票

您也可以这样做:(请参阅评论以获取解释)

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

2
投票

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

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

2
投票

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

我是按照以下方式做的

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

0
投票

您希望将 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");
        }
        }
    }

0
投票

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

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

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

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

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


0
投票

13 年后,有了最新的 C# .NET Core 等。我尝试了 Matt Davis(保护访问级别问题)和 Ryan Kohn(传递参数问题,也无法通过反射调用

OnStart
)的解决方案,但没有成功。最后我通过小小的调整就完成了,我认为这可能是一个更好的方法。

在您的服务中添加

Start
功能:

    public partial class MyService : ServiceBase {
        public void Start(string[] args = null)
        {
            OnStart(args);
        }
    }

Main
中,像这样使用它,不需要任何反射:

        static void Main(string[] args)
        {
            MyService service = new MyService ();
            if (Environment.UserInteractive)
            {
                service.Start(args);
                if (!Debugger.IsAttached)
                {
                    Console.WriteLine("Press any key to stop program");
                    Console.Read();

                    service.Stop();
                    Environment.Exit(0);
                }
            }
            else
            {
                ServiceBase.Run(service);
            }
        }

您可以在可视化代码调试模式下或作为常规 CLI 命令运行该服务。不同之处在于,当您在 VScode 中点击“停止调试”时,

OnStop
代码不会被执行。

© www.soinside.com 2019 - 2024. All rights reserved.