Just Bing It...Just Kidding
Monday, January 04, 2010

 

Historically, debugging windows services can be a minor pain. One either has to either emulate the service controller behavior using a separate console application project or install the service, start it, set a break point and attach the debugger.

 

Mimicking a console application

 

Listing 1: ServiceBase extension method

        /// <summary>
        /// Runs the service.
        /// </summary>
        /// <param name="serviceBase">The service base.</param>
        /// <param name="args">The args.</param>
        public static void RunService(this ServiceBase serviceBase, string[] args)
        {
            if (Debugger.IsAttached)
            {
                using (var autoResetEvent = new AutoResetEvent(false))
                {
                    const BindingFlags flags = BindingFlags.NonPublic | BindingFlags.InvokeMethod | BindingFlags.IgnoreCase |
                                               BindingFlags.Instance;

                    var methodInfo = serviceBase.GetType().GetMethod("OnStart", flags);
                    if (methodInfo != null)
                        methodInfo.Invoke(serviceBase, new object[] { args });

                    autoResetEvent.WaitOne();
                }
            }
            else
            {
                ServiceBase.Run(new[] { serviceBase });
            }
        }

Pretty simple stuff…check that the debugger is attached…use reflection to invoke the protected ‘OnStart’ method and block the main thread infinitely with an ‘AutoResetEvent'; otherwise, run the service as normal. Here’s the usage:

    internal static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        private static void Main()
        {
//            ServiceBase[] ServicesToRun;
//            ServicesToRun = new ServiceBase[] 
//            { 
//                new Service1() 
//            };
//            ServiceBase.Run(ServicesToRun);

            new Service1().RunService(null);
        }
    }

 

Listing 3: Key service controller event handlers

private void OnServiceTimerElapsed(object sender, ElapsedEventArgs e)
        {
            _serviceTimer.Stop();

            var dateTime = DateTime.Now;
            Debug.WriteLine(string.Format("Timer elapsed at {0} {1}...", dateTime.ToShortDateString(), dateTime.ToLongTimeString()));

            _serviceTimer.Start();
        }

        protected override void OnStart(string[] args)
        {
            _serviceTimer.AutoReset = true;
            _serviceTimer.Enabled = true;
            _serviceTimer.Start();

            Debug.WriteLine("Service started...");
        }

 

To see this in action hit F5 or run the service project instance and you can see that the service is running based on the timer elapsed event in Listing 3. service debug tracing

Monday, January 04, 2010 10:02:56 AM (Eastern Standard Time, UTC-05:00) | Comments [0] | code#
Comments are closed.
Search
Archive
Links
Categories
Admin Login
Sign In