Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to setup Topshelf with WhenCustomCommandReceived?

Tags:

c#

topshelf

I'm using Topshelf to create a windows service (ServiceClass) and i'm thinking of sending custom commands using WhenCustomCommandReceived.

HostFactory.Run(x =>
{
    x.EnablePauseAndContinue();
    x.Service<ServiceClass>(s =>
    {
        s.ConstructUsing(name => new ServiceClass(path));
        s.WhenStarted(tc => tc.Start());
        s.WhenStopped(tc => tc.Stop());
        s.WhenPaused(tc => tc.Pause());
        s.WhenContinued(tc => tc.Resume());
        s.WhenCustomCommandReceived(tc => tc.ExecuteCustomCommand());
    });
    x.RunAsLocalSystem();
    x.SetDescription("Service Name");
    x.SetDisplayName("Service Name");
    x.SetServiceName("ServiceName");
    x.StartAutomatically();
});

However, i'm getting an error on the WhenCustomCommandReceived line:

Delegate 'Action< ServiceClass, HostControl, int>' does not take 1 arguments

The signature is

ServiceConfigurator<ServiceClass>.WhenCustomCommandReceived(Action<ServiceClass, HostControl, int> customCommandReceived)

I already have methods for start, stop, pause in my ServiceClass: public void Start(), etc. Can anyone point me in the right direction on how to setup the Action? Thanks!

like image 293
Lethargic Coder Avatar asked Mar 13 '23 20:03

Lethargic Coder


1 Answers

So, as you can see in the signature of the method, the Action takes three parameters, not just one. This means that you need to set it up like this:

s.WhenCustomCommandReceived((tc,hc,command) => tc.ExecuteCustomCommand());

The interesting parameter in this case would be command which is of type int. This is the command number that is sent to the service.

You might want to change the signature of the ExecuteCustomCommand method to accept such command like this:

s.WhenCustomCommandReceived((tc,hc,command) => tc.ExecuteCustomCommand(command));

And in the ServiceClass:

public void ExecuteCustomCommand(int command)
{
    //Handle command
}

This allows you to act differently based on the command that you receive.

To test sending a command to the service (from another C# project) you can use the following code:

ServiceController sc = new ServiceController("ServiceName"); //ServiceName is the name of the windows service
sc.ExecuteCommand(255); //Send command number 255

According to this MSDN reference, the command value must be between 128 and 256.

Be sure to reference the System.ServiceProcess assembly in your test project.

like image 127
Yacoub Massad Avatar answered Mar 24 '23 06:03

Yacoub Massad