C# Windows Service - Started and then Stopped Automatically - c#

I am creating this windows service by following the instructions at MSDN Walkthrough: Creating a Windows Service and after successful installation, I go to Services.msc to Start the Windows service and before it finishes starting up I get the following message:
The EIWindowsService service on Local Computer started and then stopped. Some services stop automatically if they are not in use by other services or programs.
I know the Windows Service starts ok because there is an entry to the log file stating that the service started. I did some research before posting on here and the answer from Some Services Stop Automatically states that the problem could either be that the OnStart method is throwing an error, or that the OnStart is not kicking off a thread. So I modified my code so that the only thing within the OnStart is the starting of two timers and the log entry therefore needing no exception handling. I also added a thread to "jump" to another method.
I tried the windows service again and I know that it "moved" to the new method that the thread pointed to because I had a log entry in there that threw aFormatException error due to some conversion I was doing. I commented out the conversion and the windows service still just began to start up and then stopped automatically.
Further research indicated to me that I might need a loop to keep the processing within the method, so I took information from C - Windows Service the service on and set up an infinite while loop. I also found that there might be Garbage Collection going on and established a KeepAlive statement for the timers as suggested in Examples section of MSDN Timer Class. Still the same issues.
At this point I feel I've exhaused all the research I can do so it would be appropriate to post my question here. All my code is below and I will note that before I performed any change I uninstalled the Windows Service, removed the Setup Project, and deleted the installers from the C# code. I then made changes and started back over with the instructions in the Walkthrough starting at the point where it instructs how to setup the installers. I did this each time because I found that if I made changes and did not uninstall the Windows Service, remove the Setup Project, and delete the installers, then my changes would not take effect on the currently installed windows service.
Any assistance you can give would be most appreciated. I will be here for another 15min and then I will check this first thing tomorrow.
SERVICE1.cs
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Diagnostics;
using System.Linq;
using System.ServiceProcess;
using System.Text;
using System.Timers;
namespace EIWindowsService
{
public partial class Service1 : ServiceBase
{
Logs.ErrorLog logFile = new Logs.ErrorLog();
private System.Threading.Thread onStartThread;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
iTimer.Start();
iTimer.Elapsed += new ElapsedEventHandler(iTimer_Elapsed);
pTimer.Start();
pTimer.Elapsed += new ElapsedEventHandler(pTimer_Elapsed);
onStartThread = new System.Threading.Thread(TimerValue);
onStartThread.Start();
logFile.SendToLog("EIWindows Service started on " + GetDate());
}
catch (ArgumentOutOfRangeException ex)
{
logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "OnStart()", ex);
} //end of ArgumentOutOfRangeException CATCH statement
}
protected override void OnStop()
{
iTimer.Stop();
pTimer.Stop();
logFile.SendToLog("EIWindowsService\\Service1.cs", "OnStop()", "EIWindows Service stopped on " + GetDate());
}
private void TimerValue()
{
try
{
/*commented out because it was throwing an exception error*/
//double iTimerValue = Convert.ToDouble(iTimer.ToString());
//double pTimerValue = Convert.ToDouble(pTimer.ToString());
while (1 > 0)
{
//if (iTimerValue % 1800000 == 0) //if the timer hits the 30min mark
//{
// logFile.SendToLog("Current iTimer Value = " + iTimerValue.ToString());
//}
//if (pTimerValue % 1800000 == 0) //if the timer hits the 30min mark
//{
// logFile.SendToLog("Current pTimer Value = " + pTimerValue.ToString());
//}
GC.KeepAlive(iTimer);
GC.KeepAlive(pTimer);
}
//TimerValue();
}
catch (OverflowException ex)
{
logFile.SendToLog("OverflowException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
} //end of OverflowException CATCH statement
catch (ArgumentException ex)
{
logFile.SendToLog("ArgumentException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
} //end of ArgumentException CATCH statement
catch (FormatException ex)
{
logFile.SendToLog("FormatException", "EIWindowsService\\Service1.cs", "TimerValue()", ex);
} //end of FormatException CATCH statement
}
private string GetDate()
{
string current = "No Date Recorded";
try
{
current = DateTime.Now.ToString("F");
}
catch (FormatException ex)
{
logFile.SendToLog("FormatException", "EIWindowsService\\Service1.cs", "GetDate()", ex);
} //end of FormatException CATCH statement
return current;
} //end of method GetDate
private void iTimer_Elapsed(object source, ElapsedEventArgs e)
{
try
{
iTimer.Stop();
ImportI();
iTimer.Start();
}
catch (ArgumentOutOfRangeException ex)
{
logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "iTimer_Elapsed()", ex);
} //end of ArgumentOutOfRangeException CATCH statement
} //end of method iTimer_Elapsed
private void pTimer_Elapsed(object source, ElapsedEventArgs e)
{
try
{
pTimer.Stop();
ImportP();
pTimer.Start();
}
catch (ArgumentOutOfRangeException ex)
{
logFile.SendToLog("ArgumentOutOfRangeException", "EIWindowsService\\Service1.cs", "pTimer_Elapsed()", ex);
} //end of ArgumentOutOfRangeException CATCH statement
} //end of method pTimer_Elapsed
private void ImportI()
{
//does some action but commented out because it never gets here and is not relavant to this question.
} //end of method ImportI
private void ImportP()
{
//does some action but commented out because it never gets here and is not relavant to this question.
} //end of method ImportP
}
}
SERVICE1.DESIGNER.CS (the relavant stuff)
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.pTimer = new System.Timers.Timer(10800000); //3hrs
this.iTimer = new System.Timers.Timer(3600000); //1hr
//
// pTimer
//
this.pTimer.Enabled = true;
//
// iTimer
//
this.iTimer.Enabled = true;
//
// Service1
//
this.ServiceName = "EIWindowsService";
}
#endregion
private System.Timers.Timer pTimer;
private System.Timers.Timer iTimer;

You don't need to create a separate thread or worry about the garbage collector. The framework handles all that for you. Just create the timers and they will be called. Here's an example.
public partial class Service1 : ServiceBase
{
private Timer timer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
timer = new Timer(1000);
timer.Elapsed += new ElapsedEventHandler(timer_Elapsed);
timer.Start();
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
using (StreamWriter writer = File.AppendText(#"C:\Users\alfonso\Desktop\log.txt"))
{
writer.WriteLine(string.Format("{0} : {1}", DateTime.Now, "Logging from the service"));
}
}
protected override void OnStop()
{
}
}

Something else that may help someone coming across this post and the above solutions do not work. When I had this problem, I had added this to the config of my Windows Service:
<system.web>
<compilation debug ="true" />
</system.web>
I added this so that I could attach the debugger to the service when running it locally, however when I tried to move the service to another server it gave the specified error. By removing this from the config the service worked again.

Related

c# Windows Service starts and then stops

The code below builds without any errors and ran fine as console application. However now that I've made it into a WindowsService and used the C:\WINDOWS\Microsoft.NET\Framework\v4.0.30319\InstallUtil to successfully install it. It stops as soon as I start it up. I feel like I'm missing something simple that I'm going to forever hit myself over the head once another set of eyes looks at it.
Please forgive the mess you are about see. I will clean it up after its working properly. Thanks in advance for any help that can be provided.
Service1.cs
namespace LGCDialHome
{
public partial class Service1 : ServiceBase
{
private System.Timers.Timer _timer = null;
public Service1()
{
InitializeComponent();
System.Timers.Timer stateTimer = new System.Timers.Timer(60000);
}
protected override void OnStart(string[] args)
{
try
{
EventLog.WriteEntry("Dial Home service started : " + DateTime.Now);
_timer = new System.Timers.Timer();
_timer.Interval = 10000; //in milliseconds
EventLog.WriteEntry("Timer Interval is : " + _timer.Interval);
_timer.Elapsed += timer_Elapsed;
_timer.Start();
}
catch (Exception ex)
{
EventLog.WriteEntry("Dial Home service error : " + ex);
}
}
protected override void OnStop()
{
EventLog.WriteEntry("Dial Home service Stopped : " + DateTime.Now);
}
protected void timer_Elapsed(object sender, ElapsedEventArgs e)
{
int invokeCount = 0;
int maxCount = 10;
string host = Environment.MachineName;
string user = System.Security.Principal.WindowsIdentity.GetCurrent().Name;
string uname = Environment.UserName;
try
{
_timer.Stop();
Console.WriteLine("{0} Checking status {1,2}.",
DateTime.Now.ToString("h:mm:ss.fff"),(++invokeCount).ToString());
Console.WriteLine("Host -> {0} \r\nNTID -> {1}", host, user);
if (invokeCount == maxCount)
{
invokeCount = 0;
}
}
catch (Exception ex)
{
EventLog.WriteEntry("Dial Home service error : " + ex);
}
finally
{
_timer.Start();
}
}
}
}
Well, you will need to debug your code, but attaching to Windows Services is a little different than debugging other types of projects.
Try the following:
1- At the very beginning of your OnStart() method, add the following line:
System.Threading.Thread.Sleep(10000);
2- Set a breakpoint on the next line immediately after the line above. Build and reinstall your service using InstallUtil.
3- Start your service.
4- In Visual Studio, click Debug -> Attach to Process.
5- Find your service in the Available Processes list and attach to it. This will cause the breakpoint to be hit, and will let you debug your code to see if there's any exception thrown (by looking at your code, I feel like the problem might be security related. The user that the service is running as might not have access to the EventLog or something).
Note: After starting your service, you have 10 seconds to perform steps 4 and 5. If you think you need more time, change the sleep value to something like 20000(20 seconds).

C# Application does not crash in VS BUT CRASH on system running

I'm developing a simple test tool to verify how many HASH(SHA1) the customer server can elaborate in 1 second.
The attached sample use muti-threading to start and stop a timer that counts executed HASH.
The HASHes are sequential.
The application works well in Visual Studio, but if I run it outside the VS environment it crashes.
The problem is on increment() function in "using" section. If I comment it, everything works well!
static void increment()
{
try
{
using (SHA1 sha = new SHA1CryptoServiceProvider())
{
byte[] result;
byte[] data = new byte[20];
new Random().NextBytes(data);
result = sha.ComputeHash(data);
}
Interlocked.Increment(ref safeInstanceCount);
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
The code used to start and stop the time is the following:
bool stop;
static void Main()
{
try {
TimerQueueTimer qt;
qt = new TimerQueueTimer();
TimerQueueTimer.WaitOrTimerDelegate CallbackDelete = new TimerQueueTimer.WaitOrTimerDelegate(QueueTimerCallback);
uint dueTime = uint.Parse(textBox1.Text); // string "60000" = 1 min
uint period = 0;
qt.Create(dueTime, period, CallbackDelete);
while (!stop)
{
// Thread thread = new Thread(new ThreadStart(increment));
// thread.IsBackground = true;
// thread.Start();
increment();
}
stop = false;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
private void QueueTimerCallback(IntPtr pWhat, bool success)
{
try
{
stop = true;
}
catch (Exception ex)
{
Console.WriteLine(ex.Message);
}
}
How can I understand where is the error?
=
The application crashes without any exception.
I try to catch it, without success, it happened after 60 sec. (Maybe QueueTimerCallback is called?)
The application does not generate any error trace and it DOES not crash running under Visual Studio!
When it crashes it does not generate any stack trace, just a pop-up crash window giving in detail the "StackHash_xxxxx" error
Nothing to do! I've try to use Console.Read (it's a Windows app not console) but I cannot see anything. Here is the error shown! https://picasaweb.google.com/lh/photo/iHsBhRSy-DNTYVo4CpoeA9MTjNZETYmyPJy0liipFm0?feat=directlink
Your program is likely throwing an exception, and it's getting written to the console, but you don't have anything from stopping the console from closing immediately after the message is written.
Add a Console.ReadKey(); after your try/catch block.

Windows service starts and then stops, can't figure out the bug [closed]

Closed. This question does not meet Stack Overflow guidelines. It is not currently accepting answers.
This question does not appear to be about programming within the scope defined in the help center.
Closed 9 years ago.
Improve this question
I am trying to read a file at constant intervals and then send the data queried to a specific webserver. The following is the code I am using, but the service starts and stops without doing any thing. I can't Figure out the bug.
public partial class IPTProjectService : ServiceBase
{
private Thread checkingThread;
private System.Timers.Timer timer;
Boolean sendingTime;
public IPTProjectService()
{
InitializeComponent();
checkingThread = new Thread(update);
timer = new System.Timers.Timer(Properties.Settings.Default.TIMEINTERVAL);
timer.Elapsed += timer_Elapsed;
sendingTime = true;
}
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
setSendingTime();
if (!File.Exists("Testfile.txt"))
{
File.Create("Testfile.txt");
timer_Elapsed(sender, e);
}
else
{
File.WriteAllText("Testfile.txt", timer.ToString());
}
}
private void setSendingTime()
{
sendingTime = true;
}
private void update()
{
while (true)
{
if (sendingTime)
{
CarpoolWebClient.sendData(Properties.Settings.Default.DATAFILE);
sendingTime = false;
}
}
}
protected override void OnStart(string[] args)
{
try
{
timer.Start();
checkingThread.Start();
}
catch (Exception ex)
{
Debug.Fail(ex.ToString());
}
}
protected override void OnStop()
{
try
{
timer.Stop();
checkingThread.Abort();
}
catch(Exception e)
{
StreamWriter writer = new StreamWriter("testfile.txt", true);
writer.Write(e.ToString());
writer.Close();
}
}
}
class CarpoolWebClient
{
public static void sendData(String fileName)
{
WebRequest req = null;
WebResponse rsp = null;
try
{
//URL of message broker
string uri = "http://localhost/IPTProject/receive_xml.php";
req = WebRequest.Create(uri);
req.Method = "POST";
req.ContentType = "text/xml";
// Wrap the request stream with a text-based writer
StreamWriter writer = new StreamWriter(req.GetRequestStream());
// Write the xml text into the stream
writer.WriteLine(GetTextFromXMLFile(#fileName));
writer.Close();
rsp = req.GetResponse();
}
catch (WebException webEx)
{
//MessageBox.Show(webEx.Message);
throw webEx;
}
catch (Exception ex)
{
//MessageBox.Show(ex.Message);
throw ex;
}
finally
{
if (req != null) req.GetRequestStream().Close();
if (rsp != null) rsp.GetResponseStream().Close();
}
}
private static string GetTextFromXMLFile(string file)
{
StreamReader reader = new StreamReader(file);
string ret = reader.ReadToEnd();
reader.Close();
return ret;
}
}
If you can, debug the service. If it's a problem because the service is set to automatically start then you can use this "trick" to automatically attach the debugger and figure out what is going wrong that way.
The call to
File.Create("Testfile.txt");
timer_Elapsed(sender, e);
will create a file and return a FileStream to the newly created file. This file is subsequently still open then timer_Elapsed is called and will cause the application to fail as it cannot open the file a second time. See the MSDN Docs on the subject.
The Create call is not required for your code, you can simplyfying the method to the example below, and it should resolve this issue. Alternatively, close the FileStream object.
void timer_Elapsed(object sender, ElapsedEventArgs e)
{
setSendingTime();
File.WriteAllText("Testfile.txt", timer.ToString());
}
File.WriteAllText will create the file is it does not exist, and overwrite the file if it does exist, effectively doing the same thing as your check.
If this does not resolve the issue, check the event log for errors, or alternatively provided error handling code in your timer_Elapsed and update methods that log the error message.
As I was requesting the webserver on my own computer i.e. localhost, I didn't noticed that wampserver was not running. I checked the event log which showed me the WebException. Starting the wampserver code works fine. Thank you every one.
Yes, I encountered similar issues a lot of times...
Log all uncaught exceptions:
// Somewhere at the start of the constructor:
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
[...]
void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
// Log exeption e.ExceptionObject.ToString to a file
}
Also, I would use a try-catch + log in the update method to make sure that if the thread exits for any unknown reason, you find out the reason.
If these things don't work, it's usually something stupid like a missing DLL, the incorrect version of a DLL (64/32-bit mix), or something like that. This can be found in the event log.
That should do it :-)
If you are running this on a machine that has Visual Studio installed (e.g., your dev machine), add a call to
System.Diagnostics.Debugger.Launch();
in your startup or wherever appropriate. This will launch the Visual Studio debugger, so you don't have to fight with timing issues (Service stopping before you can manually attach the debugger)

stop windows service in onStart() method

I want to stop windows service in onStart() method when customer doesn't have a license. I use service.Stop(), but it does not work.
protected override void OnStart(string[] args)
{
try
{
_bridgeServiceEventLog.WriteEntry("new OnStart");
if (LicenseValidetor.ValidCountAndTypeDevices())
{
WsInitializeBridge();
}
else
{
service = new ServiceController("BridgeService");
service.Stop();
_bridgeServiceEventLog.WriteEntry("LicenseValidetor Error");
}
_bridgeServiceEventLog.WriteEntry("end Start");
}
catch (Exception e)
{
_bridgeServiceEventLog.WriteEntry("error In onstart method ");
}
}
You cannot stop a service from within the OnStart method of that same service.
The ServiceController.Stop method internally calls ControlService (or it's Ex counterpart). Notice that one of the reasons that this function can fail is:
ERROR_SERVICE_CANNOT_ACCEPT_CTRL
The requested control code cannot be sent to the service because the state of the service is SERVICE_STOPPED, SERVICE_START_PENDING, or SERVICE_STOP_PENDING.
Well, guess what - when you're inside your OnStart method, the state of your service is SERVICE_START_PENDING.
The correct way to cope with this situation is to signal any other threads that you may have started to have them exit, and then to exit your OnStart method. The service control manager will notice that the process has exited and revert your service status to SERVICE_STOPPED. It may also notify an interactive user that "The service started and then stopped" or words to that effect.
I want to add that "simply not starting any workers" may not work (or perhaps I am being just plain stupid ;) ).
I built a service, with a try/catch(all) around my OnStart code. Because of a missing line in my .config file it crashed with an IOException, before it started any worker thread. The exception skipped over my thread starters. No thread was started by my code. Honestly.
But the service DID NOT STOP. I don't know why. As a desperate measure, I rethrew the exception, that helped.
I am still wondering if the file system watcher threads in Enterprise Library configuration were the problem. EntLib is woven to deeply into my code to remove it as an experiment, so I did not investigate further.
The accepted answer explains why what you are doing doesn't work but doesn't offer a good solution.
There are a couple of things your code isn't doing that it should.
Set the .ExitCode to indicate that your service is in an error state.
Throw an exception. Not having a license is exceptional. Throw it.
EXAMPLE:
protected override void OnStart(string[] args)
{
_bridgeServiceEventLog.WriteEntry("new OnStart");
try
{
if (LicenseValidetor.ValidCountAndTypeDevices())
{
WsInitializeBridge();
}
else
{
throw new ApplicationException("LicenseValidetor Error");
}
}
catch (Exception e)
{
this.ExitCode = e.HResult
_bridgeServiceEventLog.WriteEntry($"error In onstart method: {e.Message}");
throw
}
_bridgeServiceEventLog.WriteEntry("end Start");
}
I have noticed that your not waiting to ensure that the Service has actually stopped or if it is even running in the first instance.
Do this :-
protected override void OnStart(string[] args)
{
try
{
_bridgeServiceEventLog.WriteEntry("new OnStart");
if (LicenseValidetor.ValidCountAndTypeDevices())
{
WsInitializeBridge();
}
else
{
int time = 10000;
TimeSpan timeout = TimeSpan.FromMilliseconds(time);
service.Stop();
service.WaitForStatus(ServiceControllerStatus.Stopped, timeout);
_bridgeServiceEventLog.WriteEntry("LicenseValidetor Error");
}
_bridgeServiceEventLog.WriteEntry("end Start");
}
catch (Exception e)
{
_bridgeServiceEventLog.WriteEntry("error In onstart method ");
}
}

Process is terminated due to StackOverflowException

This is difficult situation to explain. Have a service process that starts 2 threads, each thread loops forever but sleeps for 5 minutes each once the payload is finished.
Problem is that my second thread terminates well before the payload is even finished, for no apparent reason, and i also can't catch the exception as it seems to be triggered from outside the delegate process?
Any suggestions on how to find the problem?
The code....
public void StartService()
{
ThreadStart stRecieve = new ThreadStart(DownloadNewMail);
ThreadStart stSend = new ThreadStart(SendNewMail);
senderThread = new Thread(stRecieve);
recieverThread = new Thread(stSend);
sendStarted = true;
recieveStarted = true;
senderThread.Start();
recieverThread.Start();
}
private void DownloadNewMail()
{
while(recieveStarted)
{
//Payload....
if (recieveStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
private void SendNewMail()
{
while(sendStarted)
{
//Payload....
if (sendStarted)
{
Thread.Sleep(new TimeSpan(0, confSettings.PollInterval, 0));
}
}
}
Try to check callstack lenght in your code:
class Program
{
static void Main(string[] args)
{
try
{
Hop();
}
catch (Exception e)
{
Console.WriteLine("Exception - {0}", e);
}
}
static void Hop()
{
CheckStackTrace();
Hip();
}
static void Hip()
{
CheckStackTrace();
Hop();
}
static void CheckStackTrace()
{
StackTrace s = new StackTrace();
if (s.FrameCount > 50)
throw new Exception("Big stack!!!!");
}
}
If you are having trouble following the flow of your application's code execution, try logging the entrance of methods with a timestamp and threadid.
Also, You can't catch the exception because it is a StackOverflowException.
See msdn: "Starting with the .NET Framework version 2.0, a StackOverflowException object cannot be caught by a try-catch block and the corresponding process is terminated by default. Consequently, users are advised to write their code to detect and prevent a stack overflow. For example, if your application depends on recursion, use a counter or a state condition to terminate the recursive loop. "
Do you utlize any heavy-weight library for tasks like DownloadNewMail and SendNewMail? For example I encountered StackOverflows when running large jobs using Microsoft.SqlServer.Dts.Runtime.Package. Try running the same workload sequentially inside a command-line application to see if the issue persists.

Categories

Resources