How can a service control its own state? - c#

I have a standard windows server that inherits from the ServiceBase class.
On the OnStart method I want to check for certain conditions before I get to the main purpose of what my service does.
For example:
protected override void OnStart(string[] args)
{
if (condition == false)
{
EventLog.WriteEntry("Pre-condition not met, service was unable to start");
// TODO: Convert service state to "Stopped" because my precondition wasn't met
return;
}
InnitializeService();
}
Anybody have a good example for how a service can control its own state?

Throw an Exception. This will cause the services MMC to get an error - and the exception message and stack will automatically be logged to the event log. I use ApplicationException in this case.
In addition, the service will return to the "not running" state.
If you need to stop later on, you can call the Stop method on your ServiceBase.

The error shown the user in the "Computer Management" MMC app does not seem to get the exception text correctly in Vista. It shows the following:
The "your service name here" service
on Local Computer started and then
stopped. Some services stop
automatically if they are not in use
by other services or programs.
However it writes correctly to the Event Log just fine.
Very Cool. Thanks.

Related

Create a Windows service without the use of a timer [duplicate]

I made a Window service and let it work automatically and under localsystem account, when the service starts it fires this message for me and then stops
The [service name] service on local computer started and then stopped. Some Services stop automatically if they are not in use by another services or programs.
What's the problem and what's the solution?
Either you are not starting any threads on the OnStart method to do work, or there is an exception raised within your OnStart method.
If an exception is thrown, it will appear in the Windows Event log. The Windows Event log is a good place to start in any case.
Generally an OnStart method looks like this:
Thread _thread;
protected override void OnStart(string[] args)
{
// Comment in to debug
// Debugger.Break()
// Do initial setup and initialization
Setup();
// Kick off a thread to do work
_thread = new Thread(new MyClass().MyMethod)
_thread.Start();
// Exit this method to indicate the service has started
}
This particular error message means what it says - that your service has started but then quite soon it exited for some reason. The good news is that your service is actually doing something, so you have the executable configured and running as a service properly.
Once started, for some reason it is quitting. You need to find out why this is. Add some debugging to tell you its up and running and known exit cases. If that doesn't reveal the problem then add some debugging to let you know it's still running and work backwards from when that stops.
Are you tracing out any debug information? Most likely an exception is being thrown during your initialization. I would trace out all your exceptions and use Debugview to view them.
I had a similar problem that occurred because my Event Logs were full and the service was unable to write to them. As such, it was impossible to debug by looking for messages in the Event Viewer. I put a try/catch and dumped the exception out to a file. I had to change the settings on my logs to fill as needed instead of every 7 days and this allowed the services to start.
Of course, the root of the problem for me is that I have a nVidia driver issue that is flooding my event logs and now I'm probably beating on the disk, but that's another issue.
Maybe you need to run the service as Local System Account. See this post by Srinivas Ganaparthi.
I had the same issue starting JBoss, then I changed the JAVA_HOME variable, it worked for me. It was the JBoss version that doesn't support the 1.6, it supports 1.5.
I had similar problem and it turned out in my case that the program simply crashed in OnStart method. It tried to read some file that it couldn't find but I suppose that any other program crash would give the same result. In case of Windows forms application you would get some error message but here it was just "your service started and stopped"
If you ever need, like me to read some files from the directory where Windows Service .exe is located, check this topic:
Getting full path for Windows Service
In my case, a method in my service, was being called recursively (as no terminate condition being true) and after specific time my service was being stopped.

Restarting a service after a fatal crash

I have several services that run correctly 99.9% of the time. However, they work with network and database and occasionally an error that I have not anticipated makes it into the code and causes the service to crash. In this instance, restarting the service usually fixes the problem.
My service creates a new thread where the main code is run. I have added error handling to the service class that catches and logs any unhandled exceptions from this thread. What I am wondering is if I can call OnStop and then OnStart from the service class to restart my service?
The code that I am using is in located in the same class as OnStart and OnStop. I have posted it below:
private void ExceptionHandler(object sender, UnhandledExceptionEventArgs args)
{
log.Append("Fatal Exception:\n" + args.ExceptionObject);
eventLog.WriteEntry(log.ToString());
log = new StringBuilder();
OnStop();
if (numberOfCrashes++ < 10)
{
Thread.Sleep(60000);
OnStart(null);
log.Append("The service has been restarted " + numberOfCrashes + " times.");
eventLog.WriteEntry(log.ToString());
log = new StringBuilder();
}
}
What I am wondering is if I can call OnStop and then OnStart from the
service class to restart my service?
This will depend on how you've implemented your OnStart and OnStop logic.
For example, if your OnStart is able to determine if the working thead is already started and, if so, it stops and starts it again, then yes, you may be able to simulate a service restart by directly calling these methods.
Thus, your actual code on OnStart and OnStop is the right answer to your question, and it's up to you to refactor it to cover your requirement of programatically-restarting your service without restarting the service at the operating system level.

stop windows service programmatically c# throwing exception

I have a windows service which should stop after some particular date time.
I am able to stop the service programmatically using:
try
{
ServiceController service = new ServiceController(servicename);
//or
//ServiceController service = new ServiceController(servicename,computer name);
service.Stop();
}
catch(Exception ex)
{
}
finally
{
ServiceController service = new ServiceController(servicename);
service.Stop();
}
But it throws an exception and does not stop if we remove the finally part.
It stopped only after I used the finally statement but obviously the exception persists.
Exception message:
Cannot open "Service Name" service on computer '.'
detailed exception:
Cannot open Service Control Manager on computer 'computer name'. This operation might require other privileges.
I did refer but it does not help also it is not addresses my problem:
Stackoverflow Question
How can I stop the service programmatically without this exception
Right click on the program and choose "Run As Administrator". If you are debugging it, ensure the IDE ( ie Visual Studio I suppose ) is opened with "Run as Administrator".
When I had this problem I went to the machine in question, and tried to stop the service manually though the interface, and received this pop-up:
I was able to stop the service by finding the task in Task Manager and ending that task. Not sure what exactly hung up the service but this works if you have access to the machine and task manager.
I was able to start the service and use the ServiceController code without any issues after.

What is the proper way for a Windows service to fail during its startup

I need my service to check for existence and structure of certain files during its startup and exit/fail/stop if some conditions aren't met.
I read this thread: What is the proper way for a Windows service to fail?
but it does not help.
I set the ServiceBase.ExitCode property non-zero and then call ServiceBase.Stop. But I get 5 event log entries. See below:
Starting service. (I log this event via code)
Config.xml file not found. (I log this ERROR event via code)
Service stopped successfully. (SCM logs this message)
Service started successfully. (SCM logs this message)
Service cannot be started. The handle is invalid (SCM logs this message)
As you see everything goes OK except for the last two entries. Why are they there? What can I do to properly shutdown the service during startup? Why doesn't SCM see the service as stopped/failed?
You don't provide enough code to really know, but I suspect you are trying to validate the service and stop it in either the constructor or the OnStart. The way I like to handle services is start my timer in the OnStart. In the first interval of the timer I can validate all the code, if its invalid close the Service. If its valid, reset the interval of the timer to how frequently I want it to run then set a bool that tells it not to check for validity of files again.
What is the return code you are using for your ExitCode? If it matches the corresponding windows ExitCode, then that is what will be recorded by SCM. I'm assuming you are returning a 6 for your ExitCode.
The other thing is if you can run on Default values do that, let Config.xml be missing and just record the problem in the EventLog. "Configuration file Missing"
If you really want it to just abort during OnStart, set your ExitCode and then Throw an Exception (InvalidArgumentException, InvalidOperationException) for example
This article also has some good advice. .NET: Which Exception to Throw When a Required Configuration Setting is Missing?
You are trying to start second instance of service (another service registered for the same .exe)

Service- how to catch exit code

I would like to ask about Windows services.
My service code looks like following:
try
{
//...
}
catch
{
Environment.ExitCode = 1;
}
After I install my service I am using a scheduling system to run service at a specific time:
net start MyService
//or
sc start MyService
So my question is, how to get information if I had exception?
Is there any command to get this information? Now I am usually running my application, then after 10 mins. stopping service. I want to do intermediate scheduling task which will tell me if in the application error has occurred. I have tried all options of "sc"- but it gives only information about service.
Contraints:
I cannot log errors and exceptions into the event log or files
Prefer not to change my code
In the scheduling system I can use bat scripting (so this scipt is only place I can change something)
The standard way is to log errors and exceptions into the event log - either a specific one you create for your service, or simply using the service as a new source for the event log.
You can use WMI to then check the event log periodically for errors.
In the absence of being able to log to the event log, can you create your own "event log"? Using either a file or database table that the intermediate service polls periodically might serve your purpose.

Categories

Resources