other's comments are good and right. i just wan't to share the approach I use when developing Windows Services.
I don't want to unistall/install Service for a quick test during debug so I run them as console-applications.
So I use
Environment.UserInteractive
to check if I run from user-interaction (e.g. during debug, or by just clicking on the exe in WindowsExplorer) -> if true, I run the Service as console, by calling the OnStart-Method of the Service by reflection...
So my solution looks like this (comments and tracing ommited)
Somewhere in a helper library (it's generic and will work for all Services - just try it out):
public static void RunServices(ServiceBase[] aServicesToRun, string[] astrArgs)
{
if (Environment.UserInteractive)
{
try
{
CallServiceMethod(aServicesToRun, "OnStart", new object[] { astrArgs });
WaitPrompt(aServicesToRun);
CallServiceMethod(aServicesToRun, "OnStop", null);
}
catch (Exception ex)
{
Console.WriteLine("Service-call failed: " + ex.ToString());
Console.ReadKey(true);
}
}
else
{
ServiceBase.Run(aServicesToRun);
}
}
static void CallServiceMethod(ServiceBase[] aServicesToRun, string strMethodName, object[] aobjParams)
{
Type type = typeof(ServiceBase);
BindingFlags flags = BindingFlags.Instance | BindingFlags.NonPublic;
MethodInfo method = type.GetMethod(strMethodName, flags);
foreach (ServiceBase service in aServicesToRun)
method.Invoke(service, aobjParams);
}
private static void WaitPrompt(ServiceBase[] aServicesToRun)
{
ConsoleKeyInfo key;
do
{
key = Console.ReadKey(true);
switch (key.Key)
{
case ConsoleKey.P:
CallServiceMethod(aServicesToRun, "OnPause", null);
Console.WriteLine("Action> PAUSE");
break;
case ConsoleKey.R:
CallServiceMethod(aServicesToRun, "OnContinue", null);
Console.WriteLine("Action> RESUME");
break;
case ConsoleKey.S:
Console.WriteLine("Action> STOP");
break;
}
} while (key.Key != ConsoleKey.S);
}
Then in my Service-implementation I use it like this:
static void Main(string[] astrArgs)
{
ServiceExecutionHelper.RunServices(new ServiceBase[] { new MyService() }, astrArgs);
}
Maybe useful for you too...