Is there a clean way to exit a .net service? [duplicate] - c#

I have a service application written in C# and under certain circumstances, I would like it to terminate itself. This would happen after the service has been running for a while, so this would not be happening in the OnStart() event.
Everything that I have read so far suggests that the only safe way to terminate a service is through the Service Control Manager. My service runs as Local Service and does not have the rights to start or stop services, so I can't access the SCM from the service itself. Is there another way to self-terminate while still playing by the rules of the SCM?

Try ServiceBase.Stop().

If you want to terminate the service instead of stopping it (perhaps because the service has caught an otherwise unhandled exception) you can use Environment.Exit(1) (use another exit code if you want).
Windows will discover that the service has terminated unexpectedly. If the service has been configured to recover the recovery procedure will be used which includes options for restarting the service, running a program or restarting the computer.

What happens if you just let all the executing threads finish? I can imagine three possible outcomes:
The SCM notices, and decides you finished appropriately
The SCM notices, thinks you died, and restarts you
The SCM doesn't notice, and shows you as still running
EDIT: I suspect this answer is the best one really, but I'll leave this up (for the moment) just for the sake of interest.

Don't have the service run under Local Service. Have it run under a user that has the rights to stop a service.
Although the idea of self-terminating services is not the best of ideas. That very fact alone means that it should be an application, and not a service.

Related

Check for file existence OnStart() and then stop service [duplicate]

I have a service application written in C# and under certain circumstances, I would like it to terminate itself. This would happen after the service has been running for a while, so this would not be happening in the OnStart() event.
Everything that I have read so far suggests that the only safe way to terminate a service is through the Service Control Manager. My service runs as Local Service and does not have the rights to start or stop services, so I can't access the SCM from the service itself. Is there another way to self-terminate while still playing by the rules of the SCM?
Try ServiceBase.Stop().
If you want to terminate the service instead of stopping it (perhaps because the service has caught an otherwise unhandled exception) you can use Environment.Exit(1) (use another exit code if you want).
Windows will discover that the service has terminated unexpectedly. If the service has been configured to recover the recovery procedure will be used which includes options for restarting the service, running a program or restarting the computer.
What happens if you just let all the executing threads finish? I can imagine three possible outcomes:
The SCM notices, and decides you finished appropriately
The SCM notices, thinks you died, and restarts you
The SCM doesn't notice, and shows you as still running
EDIT: I suspect this answer is the best one really, but I'll leave this up (for the moment) just for the sake of interest.
Don't have the service run under Local Service. Have it run under a user that has the rights to stop a service.
Although the idea of self-terminating services is not the best of ideas. That very fact alone means that it should be an application, and not a service.

How to set permissions on a Windows Service

So I created a Windows Service using C# and created an installer in Visual Studio for it. It's set up to run manually as I don't want it running all the time. I then have another application (C# WPF) that should have an option to turn the service on and off (the service itself creates a web service that in turn communicates back to my WPF application). This works fine in Windows XP, but testing it on a Windows 7 machine, it won't start. Surprisingly it does throw an exception and crash, it just does nothing. I believe this is a permissions problem. If I go to the services control panel using the same Windows 7 account, I'm not able to start or stop the service either.
So my question is, is there a way to set my service so that regular user accounts can start and stop it? And is there a way to set my installer to do this automatically.
I don't want my WPF application to have run as administrator!
Whilst I believe that it is possible to secure a service so that regular users can start and stop it, I do not recommend doing so. This will create a lot of complication and is a potential cause for confusion. I always prefer to keep things simple, especially when it comes to installation and security.
So, if we can't let the user start and stop the service we probably need to let the service run all the time. Since you don't want the service to be active all the time I suggest you give the service its own internal Running flag. When this is set true, the service is active and does busy things, otherwise the service remains idle. You can use your preferred IPC mechanism (sockets, named pipes, WCF etc.) to allow the user to toggle this switch.
Windows 8 has a feature to allow services to start on demand, basically in response to some kind of trigger. But for Windows 7, your only real option is to set it to start automatically on startup. You could set it to start delayed, so that its not adding to the time it takes windows to start.
Regular users cannot start and stop services.
EDIT: Reading the link in the comment above it sounds to me as that is a blanket ability for users to start and stop services. I think the question here is about how to do this for a particular service.
Also, while it may be possible to set the service to run as that particular user, it really means it only works for that particular user and other users on the work station would not be able to use the application as they'd not be able to start or stop the service, assuming that the service running as a user implies that the user may control it, which may not be the case.
Also in reading the comments and other answer, I'm left to wonder if the service can be used by any user which can run the application. That is, if user A logs on to the work station and starts this app (and thus the service), locks it and walks away, what happens when use B logs on and tries to run the same service? Can the service support multiple users at the same time, or will funny things begin to happen if the service is utlized by the application running multiple times.
This really sounds like what is desired is for a background to be started when the application starts. This thread (or threads) would do the work of the service, and by their nature would end when the application ends. Of course more detail in the question would help give a better answer.
Of course if it is appropriate as a service, I see no reason not to have a service with a worker thread that sleeps, and another timer thread that acts as a producer that checks if there's work to do.

Windows program that always runs

I have a requirement that a Windows Forms C# .NET 2.0 program running in user-space (not a service) must always be running. As I'm not infallible and make coding mistakes, I wanted to know of any extra safeguards I could use to ensure this requirement is met. The things I've been thinking of are TaskScheduler to check it every 5 minutes, A stub watcher or a secondary process. Are these good / bad ideas?
Thanks,
Richard
EDIT: The reason I didn't use a service (the obvious and sensible answer!) was the program runs in a kiosk type environment and has has a heavy GUI component. The service option didn't work well across Windows 2000 - W7.
EDIT: The second reason not to use a service was the app needs internet access and on some of our customer sites, proxies are set up to only allow specific users (not the local system account) so it would be tricky to ensure access if multiple users log onto the machine.
Task scheduler is a cheap solution for this which does work. I use this to keep our Perforce Proxy server running (had some issues with the service), and so far there's been no problems - though now I've said that the server's probably exploded!
However, the most complete solution is a Windows service which invokes your app. You can make that service catch error return codes from the app, restart it on failure and notify you by email, which may help you diagnose and fix those issues. I think the Task Scheduler does something similar but it won't be able to provide as much insight into your application as a custom service.
If you're unsure of how to do that, then something like this should work:
http://www.codeproject.com/KB/install/csharpsvclesson1.aspx
There are three approaches that you can take:
Heartbeat Message.
A heartbeat is useful in a distributed application and is simply message that is sent (from let say a client to server) to confirm that it is still healthy/running.
Manager Process
A stub program, implemented as either a user process or a service. It launches the main application, monitors any unhandled exceptions, reports errors, and restarts on failure.
An exception guard on the entry point.
A try-catch-all in the application entry point.
I would recommend either of the first two options; the third option, the try-catch-all, is a particular nasty hack for the lazy and inexperienced programmer (IMHO).
I have successfully used both heartbeat and manager process in a large distributed application.
UPDATE
As for ready-to-go™ restart managers, take a look at the Windows API Codepack as discussed in Emmanuel Istace blog post (http://istacee.wordpress.com/2013/09/21/automatic-recovery-restart-in-net-application/).
You can install the package from https://www.nuget.org/packages/WindowsAPICodePack-Core/

Re-connect to web service?

I am using C# to write a program that uses a web service from http://msrmaps.com, the problem is sometimes (seemingly at random) the site won't work properly and will return a few different exceptions. Then on subsequent attempts to use the service I get the error over and over, then after a while (sometimes 30 minutes) the service starts working properly again. In order to avoid waiting for the service to work properly again, I usually just close my program and start it back up again. Usually that fixes the problem and I can continue to use the web service.
My question: Is it possible to restart my program within the program or better yet is there a way to somehow re-connect to the web service like the program does when I first run it?
What is the program actually doing that depends on the web service? Does it really need to be re-started? It sounds like you should be able to just have some UI element in the application that attempts to connect to the service. Wrap that connection in some exception handling and somewhere in the application's UI display that the service connection is currently unavailable.
Or am I way off here?
Warning: This is a bit of a hack, but it works.
I'm assuming your application is unattended, so a UI change alerting the user to the need to shut down and restart is not an option.
We had a similar situation where the simplest resolution to a problem was to shut down and restart my app. (We'll call this "App A").
What I wound up doing was writing a second executable (We'll call it "App B") as a console app that did two things.
It used the System.Diagnostics.Process to kill any instance App A.
Use System.Diagnostics.Process to re-launch App A after all instances were killed.
Then in App A, I had a try/catch around the offending code, and when the error I was looking for came up, it would call App B.
This was the only way I could find of killing a program and relaunching it. If anyone has a better solution, PLEASE post it and I'll change my hack to use a better solution.
I would check that you don't have too many simultaneous requests happening at the same time due to each waiting for a long time before returning (and relatedly, that the total allowed connections as per machine.config is high enough). Throttling code can be very useful with unattended use of web-services (or any other remote service), if you've had a few failures in a row then wait a while before allowing another request to be made (I like to roll forward the wait period each time, starting a around a minute, maxing the wait at around 10minutes).
Then while you can't guarantee the other service won't go down, you can help prevent it causing a permanent problem, or reducing the performance of other processes.

What are the basic applications of Windows services?

I have been quite comfortable with windows-services, I have been practicing since from last two weeks. Would you please explain me some of the basic applications of Windows service, so that I can take it as homework and practice. (it need not be too basic)
I have already designed and implemented a project/service which is meant for closing all the browsers, when I open a program(or process) saying "Gtalk".
I am interested and very eager to learn more things about Windows services.
Regards.
The word 'service' (Windows or othwerwise) implies that it is something that runs without a User Interface and possibly without any user interaction; it is constantly 'running' waiting to service commands sent to it.
a Windows service is a long-running
executable that performs specific
functions and which is designed not to
require user intervention. Windows
services can be configured to start
when the operating system is booted
and run in the background as long as
Windows is running, or they can be
started manually when required.
Ref.
You could try implementing your own scheduler? I think the most basic use of services is to have automatic process run according to a particular schedule.
Few points
The OnStart method should return within 30 seconds or the SCM will time out. OnStart should handle all initialization of your service. The constructor is called when the application's executable runs, not when the service runs. The executable runs before OnStart. When you continue, for example, the constructor is not called again because the SCM already holds the object in memory.
ServiceAccount: Some of the bugs in windows service are caused by inability to access privileged resources. Choose account type carefully or have a custom account.
Asynchronous Programming: In case you are going to connect to web services, then asynchronous programming approach is far better approach.
System.Timers.Timer: In case your service does "something" periodically, consider using System.Timers.Timer.
What can Services do under Windows?
Testing windows service

Categories

Resources