Managing Windows Services

Recently, I found I did not know enough about controlling Windows services from the command line. The Windows Services GUI is fine for some things, but it does not support useful operations, like deleting a service. After some investigation, I found just what I needed, the sc command. According to its
help documentation, "SC is a command line program used for
communicating with the NT Service Controller and services." Perfect!

When running our integration test suite, by default we install clean Code Collaborator servers for each test, running on a random available port. This prevents the activity in previous tests from corrupting the behavior of the current test (for example, by modifying a user preference). When the tests fail, they intentionally do not clean up after themselves. It means that one of the developers can go poke around on the server to diagnose the source of the problem. 

This all works well and when running the integration suite under Unix, it's trivial to clean up the mess of a failed test with judicious use of pkill and rm. However, since Code Collaborator runs as a service under Windows, the services need to be shut down and unregistered as well. Until I found the sc command, I only knew how to start and stop services using the Windows net command:

> net start myservice
> net stop myservice

This works fine if you just want to start and stop services and you know the service name. But what if you only know the prefix of the service name, as is the case with our integration tests? And how do you unregister them?

Finding All Code Collaborator Test Services


The SC command has a query subcommand, which you would think would do the trick. However, it does not seem to have a way to specify anything about the name of the service, just a few system-level things such as its state and its group. Instead, I built up a command pipeline that will do the same trick (using Cygwin tools):
sc query state= all | grep testCollab | grep SER | cut -f 2 -d " " 

The first command queries for all services. The first grep pulls out only the services with our testCollab prefix. The second grep pulls out only the SERVICE_NAME lines (not the DISPLAY_NAME lines). If the service name and display name were different, this would not be required. The cut pulls out the actual service name.

Stopping Code Collaborator Test Services

 

Since running services cannot be deleted directly, we first need to stop all the services. While we could use net stop for this purpose, the SC command has another subcommand stop that stops services. We just need to tack that onto our pipeline to stop the services. Due to some issue in the Windows command processor that I didn't bother to track down, the straightforward approach does not seem to work:
... | xargs sc stop

Results in a string of:

[SC] OpenService FAILED 1060:
The specified service does not exist as an installed service.


However, if we change the command slightly to run in a new command shell, everything seems to work:
... | xargs -n 1 cmd /C sc stop

Removing Code Collaborator Test Services

After waiting for the services to stop completely, which can take some time depending on how many are running, we just need to delete the services. Unsurprisingly, the final SC subcommand we need is called delete. We use the same command pipeline as we did when stopping the service and simply replace the command.
sc query state= all | grep testCollab | grep SER | cut -f 2 -d " " 
 | xargs -n 1 cmd /C sc delete

Thats it. All that is left to do is delete the installs, which in our case is done with ant clean. The thought just occurred to me that this functionality might be useful wrapped up in an Ant task. That's a project for another day.

Close

By submitting this form, you agree to our
Terms of Use and Privacy Policy

Thanks for Subscribing

Keep an eye on your inbox for more great content.

Continue Reading

Add a little SmartBear to your life

Stay on top of your Software game with the latest developer tips, best practices and news, delivered straight to your inbox