views:

79

answers:

2

As in the following link, one can stop, start, and "stop, then start" a service using C# code.

http://www.csharp-examples.net/restart-windows-service/

I have baked a .Net service that does implement OnStart and OnStop. However, I need to implement a "smart restart" functionality which is more involved than just stopping and then starting. I need to keep the downtime to just a few seconds if that (but Stop + Start can take minutes in this case when done cleanly, and I must do it cleanly), and having some parts of the system available while others are rebooting/refreshing.

Long story short - before I jump into implementing this OnSmartRestart functionality, I want to make sure that there is a fairly easy way to invoke this call from a other C# app.

This feature is important, but dangerous. I want to make it fairly hidden, somewhat secure, also keep it simple, and make sure that this has negligible effect on the performance of my Windows Service while it is performing its regular chores and not rebooting. If I have to poll for some file or open a port and spend too much CPU on doing that, it would not be a good solution. I also want to keep this AS SIMPLE AS POSSIBLE (sorry for repetition).

Let me know if you have questions. Thanks.

+7  A: 

You can send "commands" to a service using ServiceController.ExecuteCommand:

const int SmartRestart = 222;

service.ExecuteCommand(SmartRestart);
service.WaitForStatus(ServiceControllerStatus.Running, timeout);

The service can react to the command by overriding ServiceBase.OnCustomCommand:

protected override void OnCustomCommand(int command)
{
    if (command == SmartRestart)
    {
        // ...
    }
}
dtb
Cool - didn't know about that!
GraemeF
+1 for `0xdeadbeef`
Rubens Farias
@Rubens Farias: I just noticed that `command` must be in the range 128-256, so no `0xdeadbeef` today.
dtb
Awesome! Just what I needed. I am guessing that `readonly` might be preferable to `const` in this case ... say if I decide to change the number but do not want to rebuild both projects. Well ... depends on where the constant resides.
Hamish Grubijan
+3  A: 

The usual means of communicating with external processes in windows are:

1- Named pipes 2- Sockets 3- COM's GetObject to get a reference to an object and then calling its methods over the exposed interface.

The first two have been exposed as WCF so that is the way to go. Third one does not seem relevant to your situation and is old.

If you need to run your commands from the same machine you can use named pipes but hardening has made it very difficult and troublesome. Otherwise use WCF's TCP named binding.

Aliostad
dtb's answer is far better.
Aliostad
+1 for your comment.
Matthew Ferreira
Thanks for admission; I think it is good to leave it here anyway just for depth of the discussion.
Hamish Grubijan