How to trigger failure in a windows service? - c#

For every windows service you can define "recover policy" indicating what to do in case of a failure.
This works for when the service fail to start, but how can I trigger "failure" if the service started successfully but did something wrong while running? I tried to throw exception but the service controller just hides it, I tried to set exit code to 1 and call Stop() but it just stops gracefully..
Is there a way to tell windows "this service has crashed and want to use the recovery policy" from code and after it had successfully started? If its not possible to trigger the recover policy after started that's OK, but whats the best way to stop while indicating windows there was an error?
Thanks,

Related

C# service InvokeMethod fails during Windows shutdown

I have a Topshelf C# service that must restore adapter DNS settings when exiting. My stop/start methods work just fine and this code works:
ManagementObject.InvokeMethod("SetDNSServerSearchOrder", DNS, null);
Shutdown, however, is a problem, even with RequestAdditionalTime
I log the following error:
2016-11-30 15:10:53,427 [7] TRACE MyDNSService - DNSService Shutdown command received.
2016-11-30 15:10:53,677 [7] DEBUG MyDNSService - DNSService Error setting DNS: A system shutdown is in progress. (Exception from HRESULT: 0x8007045B)
So it appears that the OS is blocking my call to ManagementObject.InvokeMethod
I'm stymied. Is there a way around this issue? On startup my service detects the anomaly and recovers, but that takes too long. I'd really like to be able to shutdown gracefully.
Rocky, I just re-created the functional elements of your code (logging what's happening) but I'm not getting the error. I'm setting the DNSServerSearchOrder to null and feeding that to the SetDNSServerSearchOrder method of the management object. https://github.com/paulsbruce/StackOverflowExamples/blob/master/PriorityShutdown/PriorityShutdown/MyService.cs
My only additional recommendation is that you can try changing the priority of the shutdown order of your service to see if that has any effect. See this thread: .NET Windows Services stopping order when the system shutdown

.NET ServiceController.WaitForStatus ignores timeout

I've got a WinForm application and a service that does some work from the application on a server. I want the user to able to control the service from the application, so I added a ServiceController to do all the work (Start, Stop, Restart at first only). Everything works fine so far but while testing different scenarios I encountered a problem: My service is running on a server, the application is running on a client in the same network. I connect to the service and open the ServiceController.
I then shut down the server (VM) where the service is running and trigger the stop method from the client. I use the WaitForStatus method with a timeout, problem is: the timeout is seemingly ignored by the app:
public void StopService()
{
if (this._serviceController.CanStop &&
(this.ServiceStatus == ServiceControllerStatus.Running || this.ServiceStatus == ServiceControllerStatus.Paused))
{
this._serviceController.Stop();
this._serviceController.WaitForStatus(ServiceControllerStatus.Stopped, TimeSpan.FromSeconds(30));
}
}
In my case, the methods seems to try to stop the service for around 90 seconds and then throws an InvalidOperationException, which I can handle but I don't want the user to wait 90 seconds.
I think my question basically is: What happens when the timer (30 seconds in this case) runs out? Shouldn't the code just continue to run? And when does this function throw an TimeoutException? MSDN says when "The value specified for the timeout parameter expires." - but it seems like this doesn't mean after the value reaches zero.
Can someone enlighten me?
When we specify TimeSpan, WaitForStatus will rise timeout exception after waiting for given time but it seems to be you having exception on privileges.
please read this answer.

How to make window service to restart on error

I am having MSMQ on windows 2008. Messages are available in private queue. I have one WCF subscriber (written in C#) which is installed as windows service. Now problem is that sometimes the WCF subscriber stops picking messages from Queue. If I restart service again it works fine. Now I attached IError Handler to log the reason and exception.
Now to Handle this issue what I wanted to do is, I will set the recovery property to restart service on first failure and now problem is how to throw the error from HandleError() method of IErrorHandler class?
Please tell me best way to throw an exception in a window service so it can be restarted.
While it is probably better to address the underlying cause of your exceptions, it is certainly valid in certain scenarios to implement a fail fast methodology. Indeed, this ability to kill processes which have become "flawed" in some manner is critical to the concept of fault tolerance.
So, to make a windows service commit suicide:
void KillSelf()
{
try
{
// Code to close open connections/dispose
// of unmanaged resources etc
...
}
finally
{
Environment.Exit(1);
}
}
Service recovery options should be set to restart automatically. This will ensure your service comes straight back up again.
As far as I know one cannot throw an exception to restart a windows service.
I usually encapsulate a try catch (with logging) to prevent any exceptions crashing the service, which is the opposite to what you are suggesting.
It may be that you can catch an error and stop the service (not sure) and configure the service to restart if it stops?

How to programmatically create pause in Windows Service app?

I am creating a Windows Service app that I would like to have programmatically pause when either a system error, odbc connection, or missing file error occur while . I was wondering if anyone knows how to do this? The Windows service app uses an odbc connection and datareader to connect to an MS Access database and an Oracle table, so there are the probable errors that I would be handling with those, I just want to allow a pause for the user handle the errors if/when they occur.
ServiceController service = new ServiceController(serviceName);
TimeSpan timeout = TimeSpan.FromMilliseconds(timeoutValue);
service.Pause(); //or whatever you want here.
sevice.WaitForStatus(ServiceControllerStatus.Paused, timeout);
...
Then to restart, do the same thing except for
service.Continue();
sevice.WaitForStatus(ServiceControllerStatus.Running, timeout);
You can do this for any state you want. Check out the msdn documentation by googling SeviceController. It will be the first result returned.
Also, you will need to handle the OnPause and OnContinue events in your service.
Have you tried?
System.Threading.Thread.Sleep(1000); // sleep for 1 second
Adjust the 1000 to 1000 times however long you want it to sleep in seconds.
Assuming that your service has a continual loop that checks for data, add a check to an external source for pause/continue commands. This source can be a message queue like MSMQ or a database table.
I implemented something along like this by having my service continually check a table for commands, and reporting its status in another table. When it gets a start command it launches a processing loop on another thread. A stop command causes it to signal the thread to gracefully exit. The service core never stops running.
The user interacts via a separate app with a UI that lets them view the service's status and submit commands. Since the app does its control via a database it doesn't have to run on the same machine that the service is running on.

Error while stopping windows service

I am working on Windows Service. It works fine. When i am trying to stop the service from services.msc, it throws the following error:
Windows could not stop the xxx service on Local Computer.
The service did not return an error. This could be an internal Windows error or an internal service error.
If the problem persists, contact your system administrator.
If I try to stop it again, it takes lots of time and then throws the error as below:
Windows could not stop the xxx service on Local Computer.
Error 1061: The service cannot accept control messages at this time.
At this point, the service has stopped. But if I try to reinstall the service, it throws another error:
Windows could not stop the xxx service on Local Computer.
Error 1001: The specified service is marked for deletion.
After closing services.msc, it lets me reinstall the service and again things start working fine.
In OnStop(), I am doing some lengthy operations and it takes time to complete.
Any idea how I can make the whole thing go smoothly?
--Edit--
This is what my OnStop method looks like:
protected override void OnStop()
{
base.OnStop();
//Some lengthy operation
}
The windows service have a default timeout in onstart and onstop events. Normally if you are doing time consuming operations in any of these events start a new thread and let the operation to perform in background.
Usually the OnStart as well as OnStop events within the windows service are used to initiate a process and the time consuming process will carryout it's execution within a child thread.
Hope this will solve your issue..
There is a registry entry that controls how much time windows gives services to shut down before giving up: http://support.microsoft.com/kb/146092
Trivially, increasing this time would fix the issue, assuming that your service is actually shutting down after that long operation.

Categories

Resources