How to list Windows Services from within a Service - windows

sc query state= all works as expected from the command line.
From within another Service, sc query state= all doesn't print anything to that sub-process' stdout (captured by the parent, of course).
Is there a permission/privilege that the Service needs in order to list/start/stop the other servies?
A little background: I am making a service that periodically restarts some misbehaving services.

Well, for one don't do that, at least not in a blocking manner. In order for your own service to respond to the SCM (Service Control Manager) in order to return its status, the service has to be able to execute its dispatcher code. This means that if you call this program and wait for it to exit you'll wait indefinitely. One way to mitigate this would be to put this into a separate thread so it's not blocking your dispatching and your service will continue to talk to the SCM.
Alternatively (and probably better) you could use the EnumServicesStatusEx function to talk to the SCM and inquire about the statuses of other services yourself. The function itself doesn't mention anything about being blocking, so you'd have to figure out yourself whether it is and then use a thread again to prevent your service from stopping to talk to the SCM.
One last note: if those misbehaving services are yours, you should more likely fix the respective code. I've had a share of legacy code and had one misbehaving service which got its own helper application as "fault action" (can be configured in service configuration as SERVICE_CONFIG_FAILURE_ACTIONS) that would go about and restart the service whenever it crashed. Once I took that code over, figured out the cause and fixed it, the service was stable again and that application isn't really needed anymore.

Related

What is the correct way to self-terminate a MacOS XPC service?

I've successfully followed the Daemons and Service Guide - Creating XPC Services tutorial, along with the SandboxedFetch sample code and have a working Client / Service setup that is using the new NSXPCConnection class.
What still isn't entirely clear to me is how to properly self-terminate the service application once it has finished its job. I recognize that in many cases, the service is expected to remain alive, but in the use-case I have in mind, the service will be used to only to do some processing that I'd otherwise not perform in the main application. Once that processing is finished, there's no reason for the service application to remain. If the client needs another service at a later date, it can just re-create a new one.
Since the service is a lightweight, non-nibbed, NSApplication, I was trying to self-terminate it by calling invalidate from inside applicationWillTerminate, but that triggers an EXC_BAD_ACCESS exception almost every time. Calling invalidate on the service's [NSXPCListener serviceListener] generates slightly less reliable crashes, but it still crashes.
Calling invalidate from within the client application on its NSXPCConnection also generates an EXC_BAD_ACCESS exception almost every time.
So I'm curious what the correct sequence of steps is to cleanly shutdown the XPC service and then quit the service application. Ideally, the service would self-terminate after it has made its last XPC call to the client.
Attached is a small screenshot of what one of the exception's stacktrace looks like. (Yes, that's a webview that's loading in the service. Once the webview has finished loading, I want the service to self-terminate)
My first reaction is that you should not bother to terminate. When memory pressure occurs and your service is idle, launchd will kill your service. Exiting probably isn't in anyone's best interest because your service will take time to launch again. Don't terminate and you won't have to figure out why your attempt crashes.
But if for some reason you are determined to terminate, don't try so hard. Just do whatever you need to do to clean up (flush buffers, close network connections gracefully so the server doesn't suffer, whatever) and call exit. Although you seem to be using NSApplication, your service is not an application in any sense that the user cares about and there is no compelling reason to act like one in this respect. The host application needs to be able to cope with your service crashing anyway, so your deliberately exiting unceremoniously is just fine.
By the way, using NSApplication in an XPC service probably isn't the best idea because there's no supported way to declare that you want that. This might help explain why it isn't working as well as you'd like, though this paragraph should not be construed as a proper analysis of the crash. :-)

Is there a way to monitor a Windows service and alert people when it hangs/stops?

We have a service running on a Windows Server 2003 machine. This service watches a particular folder on an FTP server, and when files appear there, it invokes one of a few different executables to process them.
I've been asked to find a way for staff to be alerted in some way when this service hangs or stops.
Can anyone suggest anything with just this much information? If not, what else would you need to know?
Seems we could write ANOTHER service to watch THIS service, but then there's a chance THAT one would stop ... so we haven't resolved anything.
About the only thing that I know if is writing another application or service that monitors if that service is running; something like that shouldn't have any unexpected behavior and stop, hopefully.
Another thing to do is go to the service in Windows, go to its properties, and then go to recovery options. From here, you can set the behavior of a service if it is to fail. The options in Windows 7 are to restart the service or computer, or run a program. This program could send some sort of notification. However, I don't know if any or all of these options exist in Server 2003. This would also not likely work if the service were to just hang, but a service watching it probably wouldn't either.
Also, if you have the source code, you can override some of the service-related methods such as OnStop() (for C#) to send a notification, but I don't believe this works with a failure.
My personal choice would be to set the recovery options just to restart the service on failure, unless it repeatedly fails, which there is also an option for. But just do what you think will work best for you; there isn't really a fail-safe method to do it.
UPDATE:
I did check, and Server 2003 does indeed have the same recovery options in the service manager. As the guys said above, you can deal with that, but it is only in C++ from what I have seen; there is also a command prompt way to do it:
sc failure [servicename] reset= 0 actions= restart/60000
I found that command here and you can look at it more in its MSDN documentation. You could call this command from C# or other languages if you are not using C++, or use it directly from the command prompt if you do not have the source code.
Use ChangeServiceConfig2() to define Failure Actions for your service. You could use that to invoke an external command to issue the alert (or do pretty much anything else you want) if the service terminates unexpectedly.
The SCM (the component which handles services) has built-in auto-restart logic that you can take advantage of to restart your service, as necessary. Additionally and/or alternatively, you can configure 'custom actions' to be associated with a failure of the service - the custom action can include launching a program of your own, which could then log the failure, and perhaps manually restart your service.
You can read more about such custom actions on MSDN by looking at the documentation of the structure used to configure such actions: SERVICE_FAILURE_ACTIONS. Once you fill that structure, you notify the SCM by calling the ChangeServiceConfig2 function.
Please don't ask "well, what happens if my failure handler program crashes" :)

Stopped service does not release its resources?

I'm trying to deploy a patch to a service I created and replace the service file.
For that reason I need to stop the service so the file will be released.
I'm using sc \\remote stop svcname, then I query the service using sc \\remote query svcname until I see that it's state is STOPPED.
At this point the service file should be unlocked, and to be on the safe side I also delete the service using sc \\remote delete svcname.
Still, it doesn't seem to release the file and any deletion or change attempt fails.
I know one solution might be polling the file repeatedly, but I want to avoid this method.
Any suggestions?
Windows don't ensure the process providing the service terminates when the service is stopped (the process may provide more than one service). It just considers the service stopped when it handles the message sent to it.
So if the service process has a bug and does not properly release resources, they may still be locked. I would probably wait a little and than simply terminate the process.
There is also a tool from Microsoft called handle.exe (this is command-line version, they also have a GUI-one) that can list which processes hold the file open. It should be possible to get the same information programmatically, but I am not sure of the exact calls to make (and you need administrator privileges; you have to give them to the tool too). That way you can check whether the file is open, by which process and wait for it to terminate or force-terminate it if you didn't know which one it is.

windows service doesn't stop

I have a problem concerning a windows service that I have implemented. The service does what it has to and logs various information but when I try to stop it, it doesn't seem to stop and keeps logging.
I am not very familiar with services, so if anyone knows why this is happening please tell me.
Edit: I have tested the service on two servers and the weird thing is that on one server it stops normally, but on the other it doesn't. That is what I don't understand.
IN case you have any threads ensure that you exit those threads in your stop routine. Some threads may still be lingering which is why it does not stop.
One possible reason could be because of some remaining thread (as mentioned by 'ckv').
Have you set proper handler using RegisterServiceCtrlHandler function?
Also make sure that the SERVICE_STATUS structure that you use has its dwControlsAccepted set to accept shutdown or stop (by setting SERVICE_ACCEPT_SHUTDOWN & SERVICE_ACCEPT_STOP). and don't forget to update the service status (using SetServiceStatus function) once the service is up and running.

Restarting a windows service

I want to schedule a restart of my custom services
automatically using a batch file with net stop, net start.
When net stop runs does it abort anything that is being done
immediately?
Just wondering what will happen if in the middle of processing?
Malcolm
It will call into your code asynchronously and it will be up to you to deal with it. You could enact a clean or abort as you see fit.
It really depends on how the service is implemented. "net stop" essentially calls into the service and says "would you kindly stop". Most services will comply with this command and stop in a timely fashion. However there are the bad services which do not comply and refuse to stop. In this case, net stop will take no further action.
It really depends on the service. I suspect most will try to get into a good state before stopping. It isn't a kill.
A service registers to receive events (via RegisterServiceCtrlHandler). When you do a net stop the registered callback will receive a callback with the SERVICE_CONTROL_STOP operation. How the service responds to that callback is up to the service implementation. It would make sense for the service to do regular application shutdown processing.
Like the others said, when you call net stop, it will invoke the OnStop in the Windows Service. If the OnStop does not kill all the threads in the app, or doesn't shut everything down properly, your service might not stop. (I've seen this happen in one of our WCF services: we didn't close the ServiceHost in OnStop, and therefore, the app would not stop at our command - we'd have to kill the process by hand.)
One common pattern I've seen is to try calling stop on the service, and if it doesn't die within a timeout (10 seconds), kill the process by force. As an alternative to batch files, PowerShell has some pretty good support for dealing with services.

Resources