КАК УПРАВЛЯТЬ WINDOWS СЕРВИСОМ ИЗ ПРОГРАММЫ WINFORMS [C#]

Задание, управлять сервисом Windows из GUI программы написанной на C# WinForms. Сервис управляет модемным Интернет подкючением. Заказчик захотел иметь возможность управлять сервисом напрямую из программы. Т.е. ему нужна следующая функциональность — Остановить, Запустить, Перезапустить, отобразить текущее состояние.

Для этого нужен простой класс, который делает это при помощи стандартного ServiceController класса.

Полный код класса ниже. Этот класс умеет получать состояние сервиса, запускать, останавливать и перезапускать его.
Для ожидания изменения состояния написана асинхронная функция, которая ждет указанное время и если сервис не изменил свое состояние, бросает System.TimeoutException.

Этот класс выполняет все, что требуется, но он очень простой.
Его легко можно расширить при необходимости.

ПРИМЕЧАНИЕ: В стандартном классе ServiceController есть метод WaitForStatus. Но, не удалось заставить его правильно работать в WinForms. Поэтому более быстрым решением было написать асинхронный метод.

public static class ServiceManager
{
// ********************************************************************
public static bool IsServiceExists(string serviceName)
{
List<string> services = ServiceController.GetServices().Select(o => o.ServiceName).ToList<string>();

return services.Contains(serviceName);
}

// ********************************************************************
public static ServiceControllerStatus GetServiceStatus(string serviceName)
{
if (!IsServiceExists(serviceName))
throw new InvalidOperationException(string.Format(«Service with specified name [{0}] doesn’t exists.», serviceName));

ServiceController serviceController = new ServiceController(serviceName);

return serviceController.Status;
}

// ********************************************************************
public static string GetServiceStatusText(ServiceControllerStatus status)
{
string text = «Unknown»;

switch (status)
{
default:
break;

case ServiceControllerStatus.ContinuePending:
text = «Continue Pending»;
break;
case ServiceControllerStatus.Paused:
text = «Paused»;
break;
case ServiceControllerStatus.PausePending:
text = «Pause Pending»;
break;
case ServiceControllerStatus.Running:
text = «Running»;
break;
case ServiceControllerStatus.StartPending:
text = «Start Pending»;
break;
case ServiceControllerStatus.Stopped:
text = «Stopped»;
break;
case ServiceControllerStatus.StopPending:
text = «Stop Pending»;
break;

}

return text;
}

// ********************************************************************
public static async Task StartServiceAsync(string serviceName, int timeoutMs)
{
if (!IsServiceExists(serviceName))
throw new InvalidOperationException(string.Format(«Service with specified name [{0}] doesn’t exists.», serviceName));

ServiceController serviceController = new ServiceController(serviceName);

if (serviceController.Status == ServiceControllerStatus.Running ||
serviceController.Status == ServiceControllerStatus.StartPending)
{
// Service already started, nothing to do
return;
}

TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMs);

serviceController.Start();
await serviceController.WaitForServiceStateAsync(ServiceControllerStatus.Running, timeout);
}

// ********************************************************************
public static async Task StopServiceAsync(string serviceName, int timeoutMs)
{
if (!IsServiceExists(serviceName))
throw new InvalidOperationException(string.Format(«Service with specified name [{0}] doesn’t exists.», serviceName));

ServiceController serviceController = new ServiceController(serviceName);

if (serviceController.Status == ServiceControllerStatus.Stopped ||
serviceController.Status == ServiceControllerStatus.StopPending)
{
// Service already stopped, nothing to do
return;
}

TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMs);

serviceController.Stop();
await serviceController.WaitForServiceStateAsync(ServiceControllerStatus.Stopped, timeout);
}

// ********************************************************************
public static async Task RestartServiceAsync(string serviceName, int timeoutMs)
{
if (!IsServiceExists(serviceName))
throw new InvalidOperationException(string.Format(«Service with specified name [{0}] doesn’t exists.», serviceName));

ServiceController serviceController = new ServiceController(serviceName);

if (serviceController.Status == ServiceControllerStatus.Stopped ||
serviceController.Status == ServiceControllerStatus.StopPending)
{
// Service already stopped, nothing to do
return;
}

TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMs);

serviceController.Stop();
await serviceController.WaitForServiceStateAsync(ServiceControllerStatus.Stopped, timeout);

serviceController.Start();
await serviceController.WaitForServiceStateAsync(ServiceControllerStatus.Running, timeout);
}

// ********************************************************************
public static async Task WaitForServiceStateAsync(this ServiceController sc, ServiceControllerStatus desiredStatus, TimeSpan timeoutMs)
{
DateTime start = DateTime.Now;
while (true)
{
sc.Refresh();
if (sc.Status == desiredStatus)
break;

await Task.Delay(250);

TimeSpan ts = DateTime.Now — start;
if (ts >= timeoutMs)
throw new System.TimeoutException();
}
}
}

ОПУБЛИКОВАНО

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *