restart windows service (itself)

  • Thread starter Thread starter Leonardo Curros
  • Start date Start date
L

Leonardo Curros

Hello,
I would like to know what's the best way to restart one service. I
would like to do it from the service itself. Is this possible?
I try it with

ServiceController.stop()
ServiceController.WaitForStatus(ServiceControllerStatus.Stopped)
ServiceController.start()

but doesn´t works. It seems waitforstatus instruction is the last
instruction executed.


Thanks in advance
 
Hi there,
you can launch a separate Exe to do the job or even a batch file like
then

Service.exe /stop
Service.exe /start
 
Leonardo,
A Service can't easily restart itself, as most Windows Services only have a
single Service (a class derived from ServiceBase) in the executable (see
below). As soon as this single Service is stopped the executable is unloaded
from memory, hence your WaitForStatus is the last statement executed. Which
I fine is actually a good thing as it ensures that the entire Service is
flushed and the service's app.config file is reread.

I would consider adding a second service to the same executable, to prevent
the executable from being unloaded, which unfortunately will also prevent
the service's app.config from being reloaded.

Alternatively I would consider creating a second service in a second
executable, that is able to use your statements to restart the first. This
second one I would consider having a timer to periodically check for the
first.

Other possibilities might be to modify the Main routine generated as part of
the Windows Service (in the "Component Designer generated code" region) to
put the ServiceBase.Run statement in a loop to prevent the Main routine from
exiting, hence allowing the executable from unloading. Just remember!
depending on what you do in the Main routine, it may prevent your executable
from being unloaded!

Hope this helps
Jay
 
Thanks. But I would like to restart it only in special situations.
I try to restart it launching one separated thread with code

controller.Stop()
controller.WaitForStatus(ServiceControllerStatus.Stopped)
controller.Start()

and apparently works perfectly. Is this ok?
 
Leonardo,
Thanks. But I would like to restart it only in special situations.
I fully understand that.

When I need a service to "restart" itself, and its not because of app.config
reload, rather then use code such as yours to physically restart the service
I simply call a routine that resets my class variables. Alternatively you
could have a separate object for the real service, and your ServiceBase
class simply starts this separate object in a new AppDomain. If you need to
"restart" the ServiceBase class simply creates a new AppDomain containing a
new instance of this separate object... Using an AppDomain also causes the
app.config to reload. However its a little more work to get correct.
Alternatively if you have a separate object for the real service, you could
simply instantiate it without using an AppDomain. The AppDomain offers an
extra layer of isolation.

I do use code similar to yours when the Windows App that controls the
service needs or wants to restart the service, such as updating the
service's app.config with new parameters...
and apparently works perfectly. Is this ok?
Does it work?

Does it work reliably?

If it works & works reliably then it should be Ok.

However! My understanding is that the ServiceBase.Run will exit if all the
services that it was called with are stopped. If my understanding is
correct, your code would not work reliably, as ServiceBase.Run has exited.
However depending on how you started the second thread running (New Thread,
Thread.Background = False) the runtime will not allow your executable to
exit, keeping the service alive. My concern is your service may now be in
unstable territory...

I think my hypotheses really depends if ServiceBase.Run is implemented like
Application.Run or if it registers a call back that the Service Control
Manager (SCM, Win32 component that manages services) calls into. I really
don't know how the SCM sends the different commands to the individual
services. Note to self: what ServiceBase.Run is really doing may be a detail
that is worth investigating...

Hope this helps
Jay
 
Back
Top