ServiceController.start() and ServiceController.stop() are throwing exceptions?
The following code is throwing Exception. I don't get what mistake I am making in the code. Can somebody help me figure out please. I think it is of some security rights issue. If so, how can I give the security rights to any user or application to access this windows service programmatically?
Dim sc As New ServiceController
sc.ServiceName = "DataLoad"
If sc.Status = ServiceControllerStatus.Stopped Then
sc.Start()
Else
sc.Stop()
End If
Exception:
System.InvalidOperationException: Cannot open DataLoad service on computer '.'. --->
System.ComponentModel.Win32Exception: Access is denied --- End of inner exception stack trace --- at
System.ServiceProcess.ServiceController.GetServiceHandle(Int32 desiredAccess) at
System.ServiceProcess.ServiceController.Start(String[] args) at
System.ServiceProcess.ServiceController.Start() at
开发者_JAVA百科WEBSITE.DataLoad.Submit1_ServerClick(Object sender, EventArgs e) in C:\Inetpub\wwwroot\WEBSITE\a\DataLoad.aspx.vb:line 46
Thank you!
You can use the subinacl
tool for that
SUBINACL /SERVICE \\MachineName\ServiceName /GRANT=[DomainName\]UserName[=Access]
To be specfic for your case:
subinacl /service DataLoad /GRANT=YOURDOMAIN\[User in appdomain for WEBSITE]=TO
Where TO
means
T : Start Service
O : Stop Service
all options for [Access] are:
F : Full Control
R : Generic Read
W : Generic Write
X : Generic eXecute
L : Read controL
Q : Query Service Configuration
S : Query Service Status
E : Enumerate Dependent Services
C : Service Change Configuration
T : Start Service
O : Stop Service
P : Pause/Continue Service
I : Interrogate Service
U : Service User-Defined Control Commands
See Method 3 in this kb article
I found a solution to this problem by providing the machine name of the machine which is currently executing the service in the ServiceController overloaded constructor that takes 2(two) arguments i.e. public ServiceController(/my service's name string/, System.Environment.MachineName/this machine which is executing the service/)
The version of .Net this solution was tested on was 4.5, hope this helps anyone still looking for a solution.
Here is what you need to do in code:
ServiceController serviceController = new ServiceController("myServiceName", System.Environment.MachineName);
GetServiceHandle
requires some access rights. If it works when you run it as an Admin user, but not as a normal user, then maybe this article can help.
It clearly shows you how to manually give a Windows User rights to start and stop services (or set other permissions):
http://thommck.wordpress.com/2011/12/02/how-to-allow-non-admins-to-start-and-stop-system-services/
In my case, I determined that I needed to adjust the security on my service to allow it be be restarted by a separate "watchdog" service if my service fails.
First, open mmc.exe, then add the "Security Configuration and Analysis" and Security Templates" snap-ins.
Then create a new blank security template from the "Security Templates" item, give it a name, and hit OK to save it on your local disk drive somewhere convenient.
Then open "Security Configuration and Analysis" and choose "Open Database...", give it a name, and save it in the same directory as the previous step. When an "Import Template" window appears, open the *.inf file in the same directory.
Next, right-click "Security Configuration and Analysis" and choose "Analyze Computer..." The following will appear:
Double-click on "System Services", locate and double-click on your service, then click the checkbox "Define this policy in the database" and click on the "Edit Security" button.
This is where it becomes different than what is described in the link @JOG posted since I am using Windows 8.1--I enabled "start, stop and pause" for "INTERACTIVE" and "SERVICE"
FYI, I performed the above by following this guide as @JOG suggested: https://thommck.wordpress.com/2011/12/02/how-to-allow-non-admins-to-start-and-stop-system-services/
If you are already having the Service user as LocalSystem(the high privilage user) the problem is not security. Also I had that problem before and its the status vrs starting it again or stopping it when already commande to stop().
You see the service status its not changed on demand, so even if you coded
//this will start the process but the
//sc status will take some time to change
//when that happens and you try to start
//the already started service it will give you
//your error
servicec.start();
Soo you need to do this: msdn ServiceController.waitforstatus
Dim sc As New ServiceController
sc.ServiceName = "DataLoad"
If sc.Status = ServiceControllerStatus.Stopped Then
sc.Start()
// this makes it wait for the status to change
// and no it wont slow down anything at all.
sc.waitforstatus(ServiceControllerStatus.started)
Else
sc.Stop()
sc.waitforstatus(ServiceControllerStatus.stopped)
End If
This will solve your problem like it did mine.
精彩评论