C# Windows Service -- the service on local computer started and then stopped? - c#

I am trying to create my first Windows Service, but so sad... after I started the service manually from services.msc, the message 'the service on local computer started and then stopped. some services stop automatically is they have no work to do'
I am sure there must be some mistake in my code...
namespace ConvertService
{
public partial class Service1 : ServiceBase
{
public Service1()
{
this.ServiceName = "ConvertService";
this.EventLog.Log = "Application";
}
static void main()
{
ServiceBase.Run(new Service1());
}
protected override void OnStart(string[] args)
{
Process pMP3 = new Process();
pMP3.StartInfo.UseShellExecute = false;
pMP3.StartInfo.RedirectStandardOutput = true;
pMP3.StartInfo.FileName = #"d:\...path...\converter.exe";
pMP3.StartInfo.Arguments = #"d:\...path...\tempamr.amr " + #"d:\...path...\tempmp3.mp3 " + #"-cmp3";
pMP3.Start();
pMP3.WaitForExit();
Process pWAV = new Process();
pWAV.StartInfo.UseShellExecute = false;
pWAV.StartInfo.RedirectStandardOutput = true;
pWAV.StartInfo.FileName = #"d:\...path...\converter.exe";
pWAV.StartInfo.Arguments = #"d:\...path...\tempmp3.mp3 " + #"d:\...path...\tempwav.wav " + #"-cwav";
pWAV.Start();
pWAV.WaitForExit();
}
protected override void OnStop()
{
}
}
}
Forgive me if i did silly mistakes. This is my very very first Windows Service.
PS. I have already ticked 'Allow service to interact with desktop'

You didn't create a running thread for the OnStart method. Basically, the service manager calls OnStart to start the service, and that call needs to finish in about 15 seconds or so. Internally, you should create a thread with a loop that actually calls your code over time. Like so:
protected CancellationTokenSource _tokenSource = null;
protected Task _thread = null;
protected override void OnStart(string[] args)
{
_tokenSource = new CancellationTokenSource();
_thread = Task.Factory.StartNew(() => DoMyServiceLogic(), TaskCreationOptions.LongRunning, _tokenSource);
}
protected override void OnStop()
{
_tokenSource.Cancel();
}
protected void DoMyServiceLogic()
{
while(!_tokenSource.Token.IsCancellationRequested)
{
// Do Stuff
}
}
Your service doesn't really follow the pattern; you're not doing things continuously, and that should be more of a console program.
Effectively, it's because your service stopped doing anything as soon as you finished the OnStart method. It's like what happens when you finish Main in a console program - the application just exited.

Check to make sure the account your service runs under can access those files (including write access for the .wav and .mp3 files).
Your code might also be causing an unhandled exception. I'm not sure, but that might be visible in the event log. You can also get your service to write out messages explicitly to the event log (like in the case of an exception); check out this link: http://www.codeproject.com/KB/dotnet/simplewindowsservice.aspx

Open eventvwr.msc. There you will see exception details on why your windows service has stopped working. By the way you should as quickly as possible leave the OnStart method because you only
have 30 seconds to finish the OnStart method.
There is a excellent article on MSDN describing "how to debug" Windows Services.

Related

Windows Service Start and Stop C#

I have developed a windows service to get fingerprint attendance data from a fingerprint machine time to time by using a thread and insert into ms SQL database. When I run the service in my local computer it's working fine but when I install and run it in server 2012 the service start and then stop.Please help me out.
protected override void OnStart(string[] args)
{
new LogManagement().WriteToLog("Service Started -" + DateTime.Now);
new LogManagement().WriteToLog("Thread Started" + DateTime.Now);
RunThread();
}
protected override void OnStop()
{
new LogManagement().WriteToLog("Service Stopped -" + DateTime.Now);
}
public void RunThread()
{
Thread thread = new Thread(new ThreadStart(DeviceChecker));
thread.IsBackground = true;
thread.Name = "DeviceCheckingThread";
thread.Start();
}
private void DeviceChecker()
{
//Process reading data and insert into database
Thread.Sleep(10000);
}
Have a look at this walkthrough.
I think you need to call SetServiceStatus method (from advapi32.dll) inside your OnStart method, or Service Control Manager will shut your service down, if it takes to long for startup.

Windows Service stuck on "starting" status as local system account

I developed a http server via console application in C# and decided to turn it into a Windows service to be able to initialize it without the need to login the machine.
I followed all the steps in How to create Windows Service and chose the account as "Local System", but when I install in my server machine and push the start button it takes a while and gives the following error:
Erro 1053: The service did not respond to the start or control request in timely fashion.
After that, the service status stays stuck in "starting" and the application don't work and I can't even stop the service anymore.
Trying to work around this problem, I changed it to "Network Service", so it started normally, but the application was not listening in the port I set when I checked in the prompt with the command "netstat -an". But the application listens normally if i run it as a console application.
So I am looking for an answer to one of these two questions:
What should I do to make the service starts properly with a Local System account?
If I decide to use Network service account, what should I care about to guarantee that my service works properly as a server?
When I converted my console application to windows service I simply put my code directly in the OnStart method. However, I realized the OnStart method should start the service, but needs to end some time to the service indeed start. So I created a thread that runs my service and let the OnStart method finish. I tested and the service worked just fine. Here is how it was the code:
protected override void OnStart(string[] args)
{
Listener(); // this method never returns
}
Here is how it worked:
protected override void OnStart(string[] args)
{
Thread t = new Thread(new ThreadStart(Listener));
t.Start();
}
But I still don't understand why the service ran (passed the "starting" status, but didn't work) when I used network service account. If anyone knows, I'll be glad to know the reason.
If you have a service that is not responding or showing pending in Windows services that you are unable to stop, use the following directions to force the service to stop.
Start -> Run or Start -> type services.msc and press Enter
Look for the service and check the Properties and identify its service name
Once found, open a command prompt. Type sc queryex [servicename]
Identify the PID (process ID)
In the same command prompt type taskkill /pid [pid number] /f
Find PID of Service
sc queryex <SERVICE_NAME>
Give result's below
SERVICE_NAME: Foo.Services.Bar TYPE : 10 WIN32_OWN_PROCESS STATE : 2 0 START_PENDING (NOT_STOPPABLE, NOT_PAUSABLE, IGNORES_SHUTDOWN) WIN32_EXIT_CODE : 0 (0x0) SERVICE_EXIT_CODE : 0 (0x0) CHECKPOINT : 0x0 WAIT_HINT : 0x0 PID : 3976 FLAGS :
Now Kill the Service:
taskkill /f /pid 3976
SUCESS: The process with PID 3976 has been terminated.
Check the Windows Application event log, it could contain some entries from your service's auto generated event source (which should have the same name of the service).
For me it was a while loop that looked at an external queue. The while-loop continued running until the queue was empty. Solved it by calling a timer event directly only when Environment.UserInteractive. Therefore the service could be debugged easily but when running as a service it would wait for the timers ElapsedEventHandler event.
Service:
partial class IntegrationService : ServiceBase
{
private static Logger logger = LogManager.GetCurrentClassLogger();
private System.Timers.Timer timer;
public IntegrationService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
// Add code here to start your service.
logger.Info($"Starting IntegrationService");
var updateIntervalString = ConfigurationManager.AppSettings["UpdateInterval"];
var updateInterval = 60000;
Int32.TryParse(updateIntervalString, out updateInterval);
var projectHost = ConfigurationManager.AppSettings["ProjectIntegrationServiceHost"];
var projectIntegrationApiService = new ProjectIntegrationApiService(new Uri(projectHost));
var projectDbContext = new ProjectDbContext();
var projectIntegrationService = new ProjectIntegrationService(projectIntegrationApiService, projectDbContext);
timer = new System.Timers.Timer();
timer.AutoReset = true;
var integrationProcessor = new IntegrationProcessor(updateInterval, projectIntegrationService, timer);
timer.Start();
}
catch (Exception e)
{
logger.Fatal(e);
}
}
protected override void OnStop()
{
try
{
// Add code here to perform any tear-down necessary to stop your service.
timer.Enabled = false;
timer.Dispose();
timer = null;
}
catch (Exception e)
{
logger.Fatal(e);
}
}
}
Processor:
public class IntegrationProcessor
{
private static Logger _logger = LogManager.GetCurrentClassLogger();
private static volatile bool _workerIsRunning;
private int _updateInterval;
private ProjectIntegrationService _projectIntegrationService;
public IntegrationProcessor(int updateInterval, ProjectIntegrationService projectIntegrationService, Timer timer)
{
_updateInterval = updateInterval;
_projectIntegrationService = projectIntegrationService;
timer.Elapsed += new ElapsedEventHandler(OnTimedEvent);
timer.Interval = _updateInterval;
//Don't wait for first elapsed time - Should not be used when running as a service due to that Starting will hang up until the queue is empty
if (Environment.UserInteractive)
{
OnTimedEvent(null, null);
}
_workerIsRunning = false;
}
private void OnTimedEvent(object source, ElapsedEventArgs e)
{
try
{
if (_workerIsRunning == false)
{
_workerIsRunning = true;
ProjectInformationToGet infoToGet = null;
_logger.Info($"Started looking for information to get");
//Run until queue is empty
while ((infoToGet = _projectIntegrationService.GetInformationToGet()) != null)
{
//Set debugger on logger below to control how many cycles the service should run while debugging.
var watch = System.Diagnostics.Stopwatch.StartNew();
_logger.Info($"Started Stopwatch");
_logger.Info($"Found new information, updating values");
_projectIntegrationService.AddOrUpdateNewInformation(infoToGet);
_logger.Info($"Completed updating values");
watch.Stop();
_logger.Info($"Stopwatch stopped. Elapsed seconds: {watch.ElapsedMilliseconds / 1000}. " +
$"Name queue items: {infoToGet.NameQueueItems.Count} " +
$"Case queue items: {infoToGet.CaseQueueItems.Count} " +
$"Fee calculation queue items: {infoToGet.FeeCalculationQueueItems.Count} " +
$"Updated foreign keys: {infoToGet.ShouldUpdateKeys}");
}
_logger.Info($"Nothing more to get from integration service right now");
_workerIsRunning = false;
}
else
{
_logger.Info($"Worker is already running! Will check back again after {_updateInterval / 1000} seconds");
}
}
catch (DbEntityValidationException exception)
{
var newException = new FormattedDbEntityValidationException(exception);
HandelException(newException);
throw newException;
}
catch (Exception exception)
{
HandelException(exception);
//If an exception occurs when running as a service, the service will restart and run again
if (Environment.UserInteractive)
{
throw;
}
}
}
private void HandelException(Exception exception)
{
_logger.Fatal(exception);
_workerIsRunning = false;
}
}
You can try to increase the windows service timeout with a key in the registry
HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control
"ServicesPipeTimeout"=dword:300000 (300 seconds or 5 minutes)
If it doesn't exists it has to be created.

Prevent windows service from starting

Situation
There's a windows service given and I want to implement something like an auto-update feature. For this case I call another executable file which handles the update process.
public partial class Main : ServiceBase
{
public Main()
{
InitializeComponent();
TryUpdate();
/* Some Extra Code */
}
private void TryUpdate()
{
Process proc = new Process();
proc.StartInfo.FileName = #"UpdateCheck.exe";
proc.Start();
proc.WaitForExit();
if (proc.ExitCode != 0)
{
Process proc2 = new Process();
proc2.StartInfo.FileName = #"UpdateCheck.exe";
proc2.StartInfo.Arguments = "Update";
proc2.Start();
/* Here is where I want the application to quit! */
throw new Exception();
}
}
protected override void OnStart(string[] args)
{
/* Some Extra Code */
base.OnStart(args);
}
}
When I call the TryUpdate-Function, it starts another process which determines if there's an update available or not. If there is one, I call the process again with the parameter to update the service (it basically just waits for a few seconds so that the service can shut down and then uninstalls and installs the service using an installshield setup).
Obviously it is not the smartest solution. The problem I am facing now though is the following:
When I throw an Exception to stop the service from starting (I guess?) the application crashes and tells me the service did not respond in a timely fashion (Error 1053).
Actual Question
How do I cancel a windows service properly at this state?

Windows Services starting issue

I have windows service that is multi-threded, the threads contains while loop that should always be activated,socket thread which send errors from my other application that installed there, thread which initialize few timers
when i start the thread its start for few sec, then throw exception which says that my service stopped working and ask to send the data to Microsoft.
i don't know what make my service do it, probably the threads but i don't understand what wrong with my implementation
in addition i use custom installer, when the user start the application it will install the service.
tools is a class which contains static mathods.
my code:
public partial class MyService : ServiceBase
{
public static System.Timers.Timer key;
public static System.Timers.Timer browse;
public static System.Timers.Timer sender;
// array of worker threads
Thread[] workerThreads;
public MyService()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
workerThreads = new Thread[]
{
new System.Threading.Thread(new ThreadStart(InitTimers)),
new System.Threading.Thread(new ThreadStart(Tools.CheckApplication)),
new System.Threading.Thread(new ThreadStart(Tools.CheckBrowser)),
new System.Threading.Thread(new ThreadStart(Tools.SendOnError))
};
// start the threads
for (int i = 0; i < workerThreads.Length; i++)
{
workerThreads[i].Start();
}
}
protected override void OnStop()
{
}
public void InitTimers()
{
key = new System.Timers.Timer();
key.Interval = 1;
key.Elapsed += Other.key_Tick;
key.Enabled = true;
browse = new System.Timers.Timer();
browse.Interval = 1;
browse.Elapsed += Other.browse_Tick;
browse.Enabled = true;
sender = new System.Timers.Timer();
sender.Interval = 3600000;
sender.Elapsed += Other.sender_Tick;
sender.Enabled = true;
key.Start();
sender.Start();
browse.Start();
}
}
EDIT:
if i found the right log the exception is this:
The thread tried to read from or write to a virtual address for which it does not have the appropriate access.
never saw it... from what the exception coming from and why?
p.s the log is the log that suppose to be sent to Microsoft, i didnt create event log so i don't think i have one
I guess from your code that you are accessing the browser on the desktop.
See How can I configure my windows service in the code to access the desktop?
Read both answers, one tells you how to enable access, the other one strongly suggests another design (client app that interacts with the service)

Windows Service not completely starting

I made this small windows service in c# and I believe I may have done something wrong with my ThreadPool code that prevents my Windows Service from completely starting. If you must know, the windows service seems to be running perfectly only that when looked upon the Services console, it still states that it is "starting". When I restarted my server, the service seem to have stopped again even though I have set it to Automatic startup.
Please see my code below:
protected override void OnStart(string[] args)
{
int itemCount = itemList.Count;
this.doneEvents = new ManualResetEvent[itemCount];
for (int i = 0; i < itemCount; i++)
{
int oId = this.itemList[i];
this.doneEvents[i] = new ManualResetEvent(false);
ThreadPool.QueueUserWorkItem(data =>
{
while (this.activated)
{
DateTime start = DateTime.Now;
// my code here
// choke point
TimeSpan duration = (DateTime.Now - start);
if (duration.Milliseconds < CONST_WAITMILLISECONDS)
Thread.Sleep((CONST_WAITMILLISECONDS - duration.Milliseconds));
}
this.doneEvents[i].Set(); // thread done
}, oId);
}
WaitHandle.WaitAll(doneEvents);
}
You are blocking the OnStart call by WaitHandle.WaitAll(doneEvents);. Windows tries to start the service but times out because of WaitAll.
You need to let OnStart complete if you want Windows to treat the service as started.
I think you could wrap the logic inside OnStart in a thread. This thread would be closed when you received an OnStop event.
Something like this:
Thread _ServiceThread;
protected override void OnStart(string[] args) {
_ServiceThread = new Thread(() => { /* your current OnStart logic here...*/ });
_ServiceThread.Start();
}
protected override void OnStop() {
_ServiceThread.Stop();
}

Categories

Resources