views:

164

answers:

1

I have a Windows service that I'd like to gather some debugging data on using Intellitrace - the problem is that you can't debug a Windows Service by starting it directly from inside VS. I have the service installed, and the very first statement in Service.Start is "Debug.Break", which allows me to attach VS. However, you can't use Intellitrace if a process is already started when you attach.

Does anybody know of a workaround for this?

+2  A: 

It is possible with a little bit of work. The general idea is to mock up a console application that will call the OnStart and OnStop methods of the service. It's not the exact start and stop path a service will go through but hopefully it get you to the point that you can diagnose your issue. I included some sample code to give you a general idea.

ConsoleMock.cs:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using WindowsService1;

namespace ConsoleApplication1
{
    class Program
    {
        static void Main(string[] args)
        {
            Service1 s1 = new Service1();
            while (true)
            {
                Console.WriteLine(">1 Start\n>2 Stop");
                string result = Console.ReadLine();
                if (result == "1")
                {
                    var method = s1.GetType().GetMethod("OnStart", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    method.Invoke(s1, new object[] { args });
                }
                else if (result == "2")
                {
                    var method = s1.GetType().GetMethod("OnStop", System.Reflection.BindingFlags.NonPublic | System.Reflection.BindingFlags.Instance);
                    method.Invoke(s1, new object[] { });
                }
                else
                {
                    Console.WriteLine("wrong command");
                }
            }
        }
    }
}


Service.cs:
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Diagnostics;
    using System.Linq;
    using System.ServiceProcess;
    using System.Text;
    using System.Threading;

    namespace WindowsService1
    {
        public partial class Service1 : ServiceBase
        {
            private long serviceCounter;
            private Thread workerThread;

            public Service1()
            {
                InitializeComponent();
                serviceCounter = 0;

            }

            public void Worker()
            {
                while (true)
                {
                    serviceCounter += 1;
                    System.Threading.Thread.Sleep(500);

                    try
                    {
                        throw new Exception(serviceCounter.ToString());
                    }
                    catch (Exception)
                    {
                    }
                }
            }

            protected override void OnStart(string[] args)
            {
                workerThread = new Thread(new ThreadStart(Worker));
                workerThread.Start();
            }

            protected override void OnStop()
            {
                workerThread.Abort();
            }
        }
    }
Evan
This couldn't work any less like a champ! I've actually used it to create a stub application test my Windows service without having to attach the debugger manually - my WinForm just has a start and stop button that uses this same code, and it works perfectly. I've give you three upvotes if I could!
rwmnau