Start Stop Windows Service from UI using Asp.net MVC

Usually developer start/stop windows service using command prompt. It's a little bit longer and boring method. More than one services make the situation more complex to start or stop all services at the same time. Today, we are going to implement code to start and stop windows service using Asp.Net MVC.

I have already created windows service ASimpleService using TopShelf. You can enjoy detailed article for creating windows service using TopShelf on c-sharpcorner.com.

Let's create UI using Asp.Net MVC, Create a new ASP.NET MVC project by selecting a default MVC template. It will create HomeController and default Index action.

Before starting, we have to consider a few important points
1. We need to add System.ServiceProcess reference in our application, to use ServiceController class for accessing a windows service.
2. Verify IIS user access rights. By default, the IIS application runs under ASP.NET account without having permission to run a windows service. To overcome this problem we need to use impersonation.

To impersonate a specific user for all the requests for all pages of an ASP.NET application, you can specify the username and password attributes in the <identity> tag of the Web.config file for that application. For example:
<identity impersonate="true" userName="accountname" password="password" />
This will give rights to access whole application. This might be not a good solution to permission to the whole application for accessing only windows service. The impersonation configuration option is available in the IIS console. Read Microsoft official documentation on Configure ASP.NET Impersonation Authentication (IIS 7).

Alternatively, you can achieve impersonation for specific code by implementing Impersonate on the particular code block.
try
{
    Impersonate objImpersonate = new Impersonate(domainName, userName, userPassword);
    if (objImpersonate.impersonateValidUser())
    {
        // code for access windows service
        // ....
        objImpersonate.UndoImpersonation();
    }

}
catch (Exception exception)
{
    throw exception;
}

Here are few useful methods to control over the windows service.

Start service

StartService method will try to start a service specified by a service name. It will wait until service is running or timeout occurs.
public void StartService(string serviceName, int timeoutMilliseconds)
{
    try
    {
        ServiceController sc = new ServiceController(serviceName);
        if (sc.Status != ServiceControllerStatus.Running && sc.Status != ServiceControllerStatus.StartPending)
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
            sc.Start();
            sc.WaitForStatus(ServiceControllerStatus.Running, timeout);
        }
    }
    catch (Exception exception)
    {
        throw exception;
    }
}

Stop service

StopService will try to stop a service specified by a service name and waits until the service is stopped or a timeout occurs.
public void StopService(string serviceName, int timeoutMilliseconds)
{
    try
    {
        ServiceController sc = new ServiceController(serviceName);
        if (sc.Status == ServiceControllerStatus.Running)
        {
            TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutMilliseconds);
            sc.Stop();
            sc.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
        }
    }
    catch (Exception exception)
    {
        throw exception;
    }
}

Get Service Status

ServiceStatus method will return the status of a service specified by a service name.
public ServiceControllerStatus ServiceStatus(string serviceName)
{
    try
    {
    ServiceController sc = new ServiceController(serviceName);
    return sc.Status;
    }
    catch (Exception exception)
    {
    throw exception;
    }
}

Add below code in HomeController.cs. on HttpGet request, we will fetch the service status and display on the browser.
HomeController.cs
[HttpGet]
public ActionResult Index()
{
    ViewBag.Status = ServiceStatus("ASimpleService");
    return View();
}
        
[HttpPost]
public ActionResult Index(string submit)
{
    if (submit == "Start")
    {
        StartService("ASimpleService",1000);
    }

    if (submit == "Stop")
    {
        StopService("ASimpleService", 1000);
    }

    ViewBag.Status = ServiceStatus("ASimpleService");
    return View();
}
On Start or Stop button click, We will call StartService and StopService method accordingly.
Add start, stop buttons and label on Index.cshtml page
Index.cshtml
<h3>A Simple Service Status : @ViewBag.Status.ToString()</h3>
@using (Html.BeginForm())
{
    <input name="Submit" type="submit" @{ @((ViewBag.Status.ToString() == "Stopped") ? null : new { disabled = "disabled" }) } value="Start" />
    <input name="Submit" type="submit" @{ @((ViewBag.Status.ToString() == "Running") ? null : new { disabled = "disabled" }) } value="Stop" />
}

Result

Before running the application make sure windows service is installed. start-stop-win-service-aspnet-mvc
Image 1: Started Service
After running the application following screen (image 1) will be displayed on the browser. It will show the state of service and two buttons. Here Start button is disabled due to windows service is currently in running mode.

start-stop-win-service-aspnet-mvc
Image 2: Stopped Service
The image shows service is currently stopped.

That's all. Hope this will help you.

Summary

In this article, We have written useful codes to help developers to start or stop windows services from UI created in Asp.Net MVC. By implementing this example, we can start and stop windows service hassle free.

Reference