To debug services, I generally use the following boilerplate for Main:
static void Main()
{
ServiceBase[] servicesToRun = new ServiceBase[] { new MyService(); };
#if !DEBUG
//run the service normally using ServiceBase.Run
ServiceBase.Run(servicesToRun);
#else
//debug the process as a non-service by invoking OnStart and then sleeping
foreach (ServiceBase s in servicesToRun)
{
var serviceType = s.GetType();
var onStartMethod = serviceType.GetMethod("OnStart", System.Reflection.BindingFlags.Instance |
System.Reflection.BindingFlags.NonPublic);
onStartMethod.Invoke(s, new object[] { new string[0] });
}
Debug.WriteLine("done starting services");
while (true)
Thread.Sleep(200);
#endif
}
What this does is use reflection to get the OnStart protected method for each service, invoke it, then sit in a sleep loop to keep the process running.
This example is assuming MyService is the service class that inherits from ServiceBase, which overrides OnStart to spawn off thread(s) and do its thing.
Here I'm using the DEBUG compile-time constant as the controlling factor of whether to start normally or debug as a non-service. If DEBUG is defined it will run in-process as a non-service. Otherwise it does its normal thing calling ServiceBase.Run. Feel free to use a command-line argument or whatever works best for you.