What\'s the best way in C# to set up a utility app that can be run from the command line and produce some output (or write to a file), but that could be run as a Windows service
Yes it can be done.
Your startup class must extend ServiceBase.
You could use your static void Main(string[] args) startup method to parse a command line switch to run in console mode.
Something like:
static void Main(string[] args)
{
if ( args == "blah")
{
MyService();
}
else
{
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new MyService() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
A Windows Service is quite different from a normal Windows program; you're better off not trying to do two things at once.
Have you considered making it a scheduled task instead?
windows service vs scheduled task
The best way to accomplish this from a design standpoint is to implement all your functionality in a library project and build separate wrapper projects around it to execute the way you want (ie a windows service, a command line program, an asp.net web service, a wcf service etc.)
Yes you can.
One way to do it would be to use a command line param, say "/console", to tell the console version apart from the run as a service version:
// Class that represents the Service version of your app
public class serviceSample : ServiceBase
{
protected override void OnStart(string[] args)
{
// Run the service version here
// NOTE: If you're task is long running as is with most
// services you should be invoking it on Worker Thread
// !!! don't take too long in this function !!!
base.OnStart(args);
}
protected override void OnStop()
{
// stop service code goes here
base.OnStop();
}
}
...
Then in Program.cs:
static class Program
{
// The main entry point for the application.
static void Main(string[] args)
{
ServiceBase[] ServicesToRun;
if ((args.Length > 0) && (args[0] == "/console"))
{
// Run the console version here
}
else
{
ServicesToRun = new ServiceBase[] { new serviceSample () };
ServiceBase.Run(ServicesToRun);
}
}
}