Starting with a csharp-example and duly noting related SO questions ( Restart a windows services from C# and Cannot restart a Service) and various other questions relating to
Alright, finally implemented this. I've posted it as a separate answer as I had already come to this conclusion in the original update to my question, which was posted prior to the first answer.
Again, the StartService()
, StopService()
and RestartService()
methods follow the conventions outlined in the examples and such already referenced in the question itself (i.e. they wrap Start/Stop behavior to avoid "already started/stopped"-type exceptions) with the addendum that if a Service
is passed in (as is the case below), Refresh()
is called on that service before checking its Status
.
public static void RestartServiceWithDependents(ServiceController service, TimeSpan timeout)
{
int tickCount1 = Environment.TickCount; // record when the task started
// Get a list of all services that depend on this one (including nested
// dependencies)
ServiceController[] dependentServices = service.DependentServices;
// Restart the base service - will stop dependent services first
RestartService(service, timeout);
// Restore dependent services to their previous state - works because no
// Refresh() has taken place on this collection, so while the dependent
// services themselves may have been stopped in the meantime, their
// previous state is preserved in the collection.
foreach (ServiceController dependentService in dependentServices)
{
// record when the previous task "ended"
int tickCount2 = Environment.TickCount;
// update remaining timeout
timeout.Subtract(TimeSpan.FromMilliseconds(tickCount2 - tickCount1));
// update task start time
tickCount1 = tickCount2;
switch (dependentService.Status)
{
case ServiceControllerStatus.Stopped:
case ServiceControllerStatus.StopPending:
// This Stop/StopPending section isn't really necessary in this
// case as it doesn't *do* anything, but it's included for
// completeness & to make the code easier to understand...
break;
case ServiceControllerStatus.Running:
case ServiceControllerStatus.StartPending:
StartService(dependentService, timeout);
break;
case ServiceControllerStatus.Paused:
case ServiceControllerStatus.PausePending:
StartService(dependentService, timeout);
// I don't "wait" here for pause, but you can if you want to...
dependentService.Pause();
break;
}
}
}