Start/Stop Window Service from ASP.NET page

Update: The article has been selected as "Article of the day" on 30th April 2011 at official asp.net (http://www.asp.net) site

Last week, I needed to complete one task on which I am going to blog about in this entry. The task is "Create a control panel like webpage to control (Start/Stop) Window Services which are part of my solution installed on computer where the main application is hosted".

Here are the important points to accomplish:
[1] You need to add System.ServiceProcess reference in your application. This namespace holds ServiceController Class to access the window service.

[2] You need to check the status of the window services before you explicitly start or stop it.

[3] By default, IIS application runs under ASP.NET account which doesn't have access rights permission to window service. So, Very Important part of the solution is: Impersonation. You need to impersonate the application/part of the code with the User Credentials which is having proper rights and permission to access the window service.

If you try to access window service it will generate "access denied" error.

The alternatives are: You can either impersonate whole application by adding Identity tag in web.cofig as:
        <identity impersonate="true" userName="" password=""/>

This tag will be under System.Web section. the "userName" and "password" will be the credentials of the user which is having rights to access the window service. But, this would not be a wise and good solution; because you may not impersonate whole website like this just to have access window service (which is going to be a small part of code).

Second alternative is: Only impersonate part of code where you need to access the window service to start or stop it. I opted this one. But, to be fair; I am really unaware of the code part for impersonation. So, I just googled it and injected the code in my solution in a separate class file named as "Impersonate" with required static methods. In Impersonate class; impersonateValidUser() is the method to impersonate a part of code and undoImpersonation() is the method to undo the impersonation. Below is one example:

 Start/Stop Window Service from ASP.NET page

 You need to provide domain name (which is "." if you are working on your home computer), username and password of appropriate user to impersonate.

[4] Here, it is very important to note that: You need to have to store the Access Credentials (username and password) which you are going to user for impersonation; to some secured and encrypted format. I have used Machinekey Encryption to store the value encrypted value inside database.

[5] So now; The real part is to start or stop a window service. You are almost done; because ServiceController class has simple Start() and Stop() methods to start or stop a window service. A ServiceController class has parametrized constructor that takes name of the service as parameter.

Code to Start the window service:

Start/Stop Window Service from ASP.NET page 

Code to Stop the window service:

Start/Stop Window Service from ASP.NET page 

Isn't that too easy! ServiceController made it easy :) I have attached a working example with this post here to start/stop "SQLBrowser" service where you need to provide proper credentials who have permission to access to window service.

Start/Stop Window Service from ASP.NET page 

hope it would helps./.

Comments

# re: Start/Stop Window Service from ASP.NET page

Wednesday, March 02, 2011 8:18 AM by Sharky

Hi,

I think this is the asp code I was looking for. I copied it to my WHS and when I start the page I get a runtime error.

Can you help me out?

# re: Start/Stop Window Service from ASP.NET page

Wednesday, March 02, 2011 11:56 AM by kaushalparik27

@Sharky Please let me know the error that you are facing.

# re: Start/Stop Window Service from ASP.NET page

Thursday, March 03, 2011 8:40 AM by Ramani Sandeep

Nice post kaushal

# re: Start/Stop Window Service from ASP.NET page

Thursday, March 03, 2011 10:52 AM by kaushalparik27

@sandeep Thanks!

# re: Start/Stop Window Service from ASP.NET page

Tuesday, March 15, 2011 3:07 AM by Sharky

I get a Configuration Error.

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: It is an error to use a section registered as allowDefinition='MachineToApplication' beyond application level.  This error can be caused by a virtual directory not being configured as an application in IIS.

Source Error:

Line 29:             ASP.NET to identify an incoming user.

Line 30:         -->

Line 31:     <authentication mode="Windows"/>

Line 32:     <!--

Line 33:             The <customErrors> section enables configuration

Source File: D:\shares\Public\test\1\web.config    Line: 31

--------------------------------------------------------------------------------

Version Information: Microsoft .NET Framework Version:2.0.50727.3615; ASP.NET Version:2.0.50727.3618

I tried The Remove and Create button on the properties page, but no luck.

# re: Start/Stop Window Service from ASP.NET page

Tuesday, March 15, 2011 8:14 AM by kaushalparik27

@Sharky  - IF you are using the attached example then:

[1] you might have problem in opening the solution. You try to open it from root folder.

[2] Also, the example application is targeted to Framework 4.0

# re: Start/Stop Window Service from ASP.NET page

Monday, May 02, 2011 12:57 AM by Keval Patel

Very Good Article. Keep It up :)

# re: Start/Stop Window Service from ASP.NET page

Monday, May 02, 2011 4:21 AM by grasu5xl

I just did something similar but instead of impersonation i gave the user under which the asp.net application specific rights to stop/start/etc the service. At first i used subinacl, but afterward i needed to grant the permissions programtically, so used wmi, if you would like i could give you the code to do this. Cheers.

# re: Start/Stop Window Service from ASP.NET page

Monday, May 02, 2011 4:25 AM by kaushalparik27

@grasu5xl <<if you would like i could give you the code to do this>>

Sure, If you can share. This will be great! Thanks.

# re: Start/Stop Window Service from ASP.NET page

Monday, May 02, 2011 2:30 PM by Prakash

Can we stop IIS? means IIS service in remote server

# re: Start/Stop Window Service from ASP.NET page

Monday, May 02, 2011 10:01 PM by kaushalparik27

@Prakash Try out below link. This might help you.

www.codeproject.com/.../Start_Stop_IIS_Website.aspx

# re: Start/Stop Window Service from ASP.NET page

Tuesday, May 03, 2011 2:16 PM by grasu5xl

This is the function that sets the bitmask.

Public Shared Function SetBitmask(ByVal ServiceName As String, ByVal UserName As String, ByVal bitmask As UInt32) As Int32

       Dim wmi As WmiHelper = New WmiHelper("root\cimv2")

       Dim service As ManagementObject = wmi.GetInstance(".", String.Format(" SELECT * FROM Win32_Service WHERE Name = '{0}'", ServiceName))

       Dim outParams As ManagementBaseObject = service.InvokeMethod("GetSecurityDescriptor", Nothing, Nothing)

       Dim sd As ManagementBaseObject = outParams("Descriptor")

       Dim dacls As ManagementBaseObject() = sd("DACL")

       Dim sacls As ManagementBaseObject() = sd("SACL")

       Dim ctrlFlags As UInt32 = sd("ControlFlags")

       Dim newDescriptor As ManagementBaseObject = wmi.GetClass("Win32_SecurityDescriptor").CreateInstance

       'Create previous DACLs

       Dim newDaclList As New List(Of ManagementBaseObject)

       For Each dacl As ManagementBaseObject In dacls

           'Ignore the DACL if it belongs to the User we are trying to assign a new DACL to.

           If Not dacl("Trustee")("Name") = UserName Then

               newDaclList.Add(dacl)

           End If

       Next

       'Create new DACL

       Dim customDaclACE As ManagementBaseObject = wmi.GetClass("Win32_ACE").CreateInstance

       Dim newTrustee = SecurityUtils.GetTrustee(SecurityUtils.GetSid(UserName, Nothing))

       customDaclACE.Properties("Trustee").Value = newTrustee

       Dim newAccessMask As UInt32 = bitmask

       customDaclACE.Properties("AccessMask").Value = newAccessMask

       newDaclList.Add(customDaclACE)

       'Add DACL

       newDescriptor.Properties("DACL").Value = newDaclList.ToArray

       'Add owner & group

       newDescriptor.Properties("Owner").Value = sd.Properties("Owner").Value

       newDescriptor.Properties("Group").Value = sd.Properties("Group").Value

       'Add control flags

       newDescriptor.Properties("ControlFlags").Value = ctrlFlags

       'add SACL

       newDescriptor.Properties("SACL").Value = sd.Properties("SACL").Value

       'Submit new SecurityDescriptor

       Dim inParams As ManagementBaseObject = service.GetMethodParameters("SetSecurityDescriptor")

       inParams("Descriptor") = newDescriptor

       Dim ret As ManagementBaseObject = service.InvokeMethod("SetSecurityDescriptor", inParams, Nothing)

       'Clean up on aisle 5 :)

       service.Dispose()

       sd.Dispose()

       newDescriptor.Dispose()

       Return CInt(ret("ReturnValue"))

   End Function

Public Enum ServiceAccessRights

   ACCESS_ALLOWED_ACE_TYPE = &H0

   SERVICE_QUERY_CONFIG = &H1

   SERVICE_CHANGE_CONFIG = &H2

   SERVICE_QUERY_STATUS = &H4

   SERVICE_ENUMARATE_DEPEND = &H8

   SERVICE_START = &H10

   SERVICE_STOP = &H20

   SERVICE_PAUSE_CONTINUE = &H40

   SERVICE_INTEROGATE = &H80

   READ_CONTROL = &H20000

   SERVICE_USER_DEFINED_CONTROL = &H100

End Enum

Also while connecting to the wmi, ConnectionOptions.EnablePrivilages = True

I will not be posting the wmihelper class.

# re: Start/Stop Window Service from ASP.NET page

Tuesday, May 03, 2011 2:18 PM by grasu5xl

Also the function is called as followed

Dim bitmask As UInt32 = ServiceAccessRights.ACCESS_ALLOWED_ACE_TYPE Or ServiceAccessRights.SERVICE_QUERY_STATUS

Dim retValue As Integer = ServiceSecurityUtils.SetBitmask(serviceName, userName, bitmask)

# re: Start/Stop Window Service from ASP.NET page

Thursday, May 12, 2011 8:29 AM by Mehul Trivedi

Good article to start with!

# re: Start/Stop Window Service from ASP.NET page

Tuesday, September 27, 2011 10:03 AM by D.J. Reese

thanks for the script! :) Need a little assistance if you are able. I do not know ASP at all so bare with me! I copied all your files into a folder inside IIS7 and then tried to run it. I got the same error as Sharky did above and I converted the folder to an application and it got past the previous error. Now im getting this:

Configuration Error

Description: An error occurred during the processing of a configuration file required to service this request. Please review the specific error details below and modify your configuration file appropriately.

Parser Error Message: Unrecognized attribute 'targetFramework'. Note that attribute names are case-sensitive.

Source Error:

Line 18:             during development.

Line 19:         -->

Line 20:     <compilation debug="true" targetFramework="4.0">

Line 21:       <assemblies>

Line 22:         <add assembly="System.ServiceProcess, Version=4.0.0.0, Culture=neutral, PublicKeyToken=B03F5F7F11D50A3A"/>

Source File: C:\inetpub\wwwroot\new\web.config    Line: 20

--------------------------------------------------------------------------------

Version Information: Microsoft .NET Framework Version:2.0.50727.5446; ASP.NET Version:2.0.50727.5420

Any thoughts?

# re: Start/Stop Window Service from ASP.NET page

Wednesday, September 28, 2011 1:55 AM by kaushalparik27

Hello D.J. Reese,

Check out the error again.. The application is expecting targetFramework=4.0; but last error line shows version information that the virtual directory is configured to use.

Here is the line i copied from the error that you sent:

Version Information: Microsoft .NET Framework Version:2.0.50727.5446; ASP.NET Version:2.0.50727.5420

So, what you need to do is create a separate Application Pool which uses frameWork 4.0 and assign that application pool to Virtual Directory of the application.

This should work.

Hope it helps./.

# re: Start/Stop Window Service from ASP.NET page

Wednesday, September 28, 2011 8:33 AM by D.J. Reese

thanks!! it worked like a charm! I got an error on running it again but i forgot to make it an application. After doing so it works. I am getting this error though when I run it (i changed the service to the "Spooler" service because the box i am on does not have SQL installed)

**** Cannot open Spooler service on computer '.'.Access is denied **** I changed the domainName string to reference my domain and also the username and password fields. thanks for the great script! Been looking for something like this for quite some time!

# re: Start/Stop Window Service from ASP.NET page

Wednesday, September 28, 2011 8:58 AM by kaushalparik27

Hello D.J. Reese

**** Cannot open Spooler service on computer '.'.Access is denied ****

For this error; I would check if the domain username/password that are being used to access the Spooler window service is having proper access permission or not to stop/start it.

# re: Start/Stop Window Service from ASP.NET page

Wednesday, September 28, 2011 4:22 PM by D.J. Reese

Nice thought! Yeah i was using my username and password but, in other ASP scripts like this one where impersonate was being used, it wasnt working. My account is a domain admin but... whatever!! its working. Only thing now is that the service DOES stop but it doesnt start back up after pressing start service! Any thoughts?

# re: Start/Stop Window Service from ASP.NET page

Wednesday, September 28, 2011 5:28 PM by kaushalparik27

"Pressing Start Service" .. IS that giving you any error or something?

# re: Start/Stop Window Service from ASP.NET page

Thursday, September 29, 2011 10:28 AM by D.J. Reese

No - It says that the service is started but the actual service doesnt start. It says "SpoolerWindow service start success".

# re: Start/Stop Window Service from ASP.NET page

Tuesday, February 28, 2012 8:21 AM by BelAbz

Your code is amazing ...

I'm running it on Windows 2008 Server,  It says that the service is started but the requested Service doesn't start.

Any advice please ??

Thank you.

# re: Start/Stop Window Service from ASP.NET page

Thursday, December 06, 2012 2:19 AM by sundar

Hi

   Which domain name, username and password should give sir.

Leave a Comment

(required) 
(required) 
(optional)
(required)