I have written a TopShelf service / console app, which appears to be running as intended, except I would like it to run once on boot, then disable itself until the next boot/reboot.
I was hoping this would work:
class MyServiceClass
{
public void Start()
{
// do the things that need doing
this.Stop();
}
public void Stop()
{
}
But that doesn't work, presumably because the this.Stop() command is there for cleanup, not for causing the service to stop.
My Program.cs looks like this:
// Uses Topshelf: http://topshelf-project.com/
// Guided by: http://www.ordina.nl/nl-nl/blogs/2013/maart/building-windows-services-with-c-and-topshelf/
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using Topshelf;
namespace MyNamespace
{
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
hostConfigurator.Service<MyServiceClass>(serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => new MyServiceClass());
serviceConfigurator.WhenStarted(myServiceClass => myServiceClass.Start());
serviceConfigurator.WhenStopped(myServiceClass => myServiceClass.Stop());
});
hostConfigurator.RunAsLocalSystem();
hostConfigurator.SetDisplayName("MyService");
hostConfigurator.SetDescription("Does stuff.");
hostConfigurator.SetServiceName("MyService");
hostConfigurator.StartAutomatically();
hostConfigurator.EnableShutdown();
});
}
};
}
How do I go about stopping the service at the end of execution?
UPDATE: Based on Damien's input, I now have:
public class MyServiceClass
{
private readonly Task task;
private HostControl hostControl;
public MyServiceClass()
{
task = new Task(DoWork);
}
private void DoWork()
{
Console.WriteLine("Listen very carefully, I shall say this only once");
hostControl.Stop();
}
public void Start(HostControl hostControl)
{
// so we can stop the service at the end of the check
this.hostControl = hostControl;
// start the DoWork thread
task.Start();
}
public void Stop()
{
}
};
and an updated Program.cs
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
hostConfigurator.Service<MyServiceClass>((serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => new MyServiceClass());
serviceConfigurator.WhenStarted((myServiceClass, hostControl) => myServiceClass.Start(hostControl));
serviceConfigurator.WhenStopped(myServiceClass => myServiceClass.Stop());
}); /* compiler thinks there's a ")" missing from this line */
hostConfigurator.RunAsLocalSystem();
hostConfigurator.SetDisplayName("MyService");
hostConfigurator.SetDescription("Does stuff.");
hostConfigurator.SetServiceName("MyService");
hostConfigurator.StartAutomatically();
hostConfigurator.EnableShutdown();
});
}
};
However, this will not compile. My compiler suggests that a ")" is missing on (or around) my comment (shown in the code above), but any addition of a close parenthesis just adds to the error list.
I feel like I'm close... any ideas?
Got this working eventually:
public class MyServiceClass : ServiceControl
{
private readonly Task task;
private HostControl hostControl;
public MyServiceClass()
{
task = new Task(DoWork);
}
private void DoWork()
{
Console.WriteLine("Listen very carefully, I shall say this only once");
//hostControl.Stop();
}
public bool Start(HostControl hostControl)
{
// so we can stop the service at the end of the check
this.hostControl = hostControl;
// start the DoWork thread
task.Start();
return true;
}
public bool Stop(HostControl hostControl)
{
return true;
}
};
and
class Program
{
static void Main(string[] args)
{
HostFactory.Run(hostConfigurator =>
{
hostConfigurator.Service<MyServiceClass>(serviceConfigurator =>
{
serviceConfigurator.ConstructUsing(() => new MyServiceClass());
serviceConfigurator.WhenStarted((myServiceClass, hostControl) => myServiceClass.Start(hostControl));
serviceConfigurator.WhenStopped((myServiceClass, hostControl) => myServiceClass.Stop(hostControl));
});
hostConfigurator.RunAsLocalSystem();
hostConfigurator.SetDisplayName("MyService");
hostConfigurator.SetDescription("Does stuff.");
hostConfigurator.SetServiceName("MyService");
hostConfigurator.StartAutomatically();
hostConfigurator.EnableShutdown();
});
}
};
My 2nd attempt had a spare "(" at the first mention of serviceConfigurator, then I needed to turn my void Start and Stop functions into bool functions. Hope this helps someone.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With