32

How to run a windows service project from visual studio.

I am building a windows serivce in visual studio 2008, I have to always run the service from control panel and then attach the debugger to running instance of the service. Its kind of annoying since I am cleaning a lot of code and need to restart my service many times during development.

I want to setup my project so as to be able to hit F5 and run the service and directly enter the debug mode. Some tips on how to achieve this would be great.

Thanks in advance!!!

Pomster
  • 12,548
  • 52
  • 122
  • 196
dotnetcoder
  • 3,223
  • 7
  • 49
  • 77
  • Look this article http://msdn.microsoft.com/en-us/library/7a50syb3(v=vs.80).aspx. It also refers to the following articles: http://msdn.microsoft.com/en-us/library/htkdfk18(v=vs.80).aspx http://msdn.microsoft.com/en-us/library/ddhy0byf(v=vs.80).aspx –  May 10 '12 at 10:37

8 Answers8

32

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

This should allow you to run from within Visual Studio.

Another way would be to embed a programmatic breakpoint in your code by calling System.Diagnostics.Debugger.Break(). When you place this in, say, the OnStart() callback of your service and start your service from the Services console, the programmatic breakpoint will trigger a dialog box that allows you to attach to an existing instance of Visual Studio or to start a new instance. This is actually the mechanism I use to debug my service.

Matt Davis
  • 43,149
  • 15
  • 89
  • 118
  • Just FYI, in Windows 8, it would seem they've made some changes to windows services and cut back alot on their ability to do interactive things. Debugger.Launch() and Debugger.Break() no longer seem to trigger the GUI Dialog which allowed you to choose and IDE to debug so the service just hangs. FYI – Eoin Campbell Nov 23 '12 at 12:35
  • A couple of notes: 1- As OnStart & OnStop are protected methods and called be called from external class, add a public DoStart & DoStop to do the actual work. 2- If the project type is kept as Windows Application, Console.Read will throw an exception so change the project type to Console Application. – sh_kamalh Jan 14 '20 at 12:21
  • I have a service which get installations configurations from a XML file and I want to validate it before install. I want to debug that process, so how can I debug service before installing using Visual Studio. I am using VS2019 – Buddhika Chathuranga Apr 11 '20 at 07:57
  • @hackerbuddy See if this helps. https://stackoverflow.com/questions/4525450/can-i-develop-a-windows-service-that-can-be-both-a-windows-service-and-a-any/4525840#4525840 – Matt Davis Apr 11 '20 at 16:24
7

In your Main() routine check for Debugger.IsAttached and if it's true start your app as if it's a console, if not, call into ServiceBase.Run().

Samuel Neff
  • 67,422
  • 16
  • 123
  • 169
4

It's possible to set up a companion project to the Windows Service that runs as a console app, but accesses the service methods using Reflection. See here for details and an example: http://ryan.kohn.ca/articles/how-to-debug-a-windows-service-in-csharp-using-reflection/.

Here is the relevant code that you'll need in the console application:

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
    }
  }
}
Ryan Kohn
  • 11,921
  • 10
  • 50
  • 80
2

You can also do this: (See comments for explanation)

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

Create a seperate project that just references the service project and instantiate and start the service. It just runs like a normal app and you can step into it.

YourService s = new YourService();
s.Start();
Patrick Kafka
  • 9,516
  • 3
  • 27
  • 43
2

Just call the OnStart() event from the service constructor

I did it in the following way

    public XXX()
    {
        InitializeComponent();
        OnStart(new string[] { "shafi", "moshy" });
    }
shafyxl
  • 21
  • 1
0

You want to have your windows service as a shell, there should be little code in there so you don't have to test it.

You should have every thing you want your service to do in a class.

You can unit test you class and if it works then reference it to your service.

This way when you have you class doing every thing you want then when its applied to your service every thing should work. :)

Will an event log you can see what your service is doing while it is running, also a nice way to test :D try that.

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");
        }
        }
    }
Pomster
  • 12,548
  • 52
  • 122
  • 196
0

These links can be very helpful when working with services.

This is a walk though on creating them http://msdn.microsoft.com/en-us/library/zt39148a.aspx

James Michael Hare has on his blog http://geekswithblogs.net/BlackRabbitCoder/ written about a really nice template/framework he has made, making it lot easier to develop (and debug) Windows Services: C# Toolbox: A Debuggable, Self-Installing Windows Service Template (1 of 2) http://geekswithblogs.net/BlackRabbitCoder/archive/2010/09/23/c-windows-services-1-of-2-creating-a-debuggable-windows.aspx

It provides you with all the basics you need to quickly get started. And best of all, it give you a really nice way to debug your service as if it was a regular console application. I could also mention that it provides out of the box functionality to install (and uninstall) your service. Part two of the post can be found at this link.

I've used this myself a couple of times, and can really recommend it.

Pomster
  • 12,548
  • 52
  • 122
  • 196