Reputation: 5341
Trying to deubg a windows service (removed the need to install, code, install, code, etc..), thought I found the solution
class Program
{
static void Main(string[]args)
{
ClientService service = new ClientService();
if (args.Length > 0)
{
Task.Factory.StartNew(service.Main, TaskCreationOptions.LongRunning);
Console.WriteLine("running...");
Console.ReadLine();
}
else
{
#if (!DEBUG)
ServiceBase[]ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
# else
ServiceBase.Run(service);
}
# endif
}
}
However I'm still getting the error:
Cannot start service from the command line or debugger. A windows Service must first be installed(using installutil.exe) and then started with the ServerExplorer, Windows Services Administrative tool or the NET START command.
Any Ideas what I need to change to avoid the prompt?
Upvotes: 2
Views: 12899
Reputation: 151588
You have copied the code from Running Windows Service Application without installing it, but it was broken by design and you altered it incorrectly.
The thought behind it, is that you have a ServiceBase
-inheriting class containing a public method that performs the actual service logic:
public class MyService : ServiceBase
{
public void DoTheServiceLogic()
{
// Does its thing
}
public override void OnStart(...)
{
DoTheServiceLogic();
}
}
Then in your application, you can start it like this:
class Program
{
static void Main(string[] args)
{
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
}
}
This provides an executable application that can be installed as a Windows Service.
But you don't want to have to install your service and then attach Visual Studio to debug it; that's a horribly inefficient workflow.
So what the code you found attempts to do, as many approaches found online do, is to start the application with a certain command line flag, say /debug
, which then calls the public method on the service logic - without actually running it as a Windows Service.
That can be implemented like this:
class Program
{
static void Main(string[] args)
{
if (args.Length == 1 && args[0] == "/debug")
{
// Run as a Console Application
new MyService().DoTheServiceLogic();
}
else
{
// Run as a Windows Service
ServiceBase[] ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
}
}
}
Now you can instruct Visual Studio to pass the /debug
flag when debugging your application, as explained in MSDN: How to: Set Start Options for Application Debugging.
That's slightly better, but still a bad approach. You should extract the service logic altogether, and write unit tests to be able to test your logic without having to run it inside an application, let alone a Windows Service.
Upvotes: 8
Reputation: 378
In Program.cs
class Program
{
static void Main(string[] args)
{
#if DEBUG
new ClientService().Start();
Thread.Sleep(Timeout.Infinite); //Ensure your service keeps running
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
}
In ClientService.cs
public void Start()
{
OnStart(null);
}
Upvotes: 0
Reputation: 974
Here is what you can do:
Create a partial class with the same name as tour service:
public partial class AlertEngineService
{
public void Run(string[] args)
{
OnStart(args);
Console.WriteLine("Press any key to stop program alert engine service");
Console.Read();
OnStop();
}
}
}
and call this command on debug:
var servicesToRun = new ClientService ();
servicesToRun.Run(args);
you can also change the service configuration to run as console (in the properties section).
Hope it helps
Upvotes: 2
Reputation: 5920
Start with changing your code a bit :
static void Main(string[] args)
{
#if DEBUG // If you are currently in debug mode
ClientService service = new ClientService (); // create your service's instance
service.Start(args); // start this service
Console.ReadLine(); // wait for user input ( enter key )
#else // else you're in release mode
ServiceBase[] ServicesToRun; // start service normally
ServicesToRun = new ServiceBase[]
{
new MyService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
In your service add this method :
public void Start(string[] args)
{
OnStart(args);
}
Now all you need to change is in properties change application type from Windows Application
to Console Application
.
Upvotes: 0