I'm currently writing a windows service which connects to a crm system to pull down a schedule which then runs various datafeeds etc. I've got everything working except when I install everything and try to run start the service I get the following error :
"Error 1053: The service did not respond to the start or control request in a
timely fashion"
Here's the code I'm using in my Service1.cs;
namespace FeedManagementService
{
public partial class Service1 : ServiceBase
{
private System.Timers.Timer timer;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
// Instantiate the timer
Thread t = new Thread(new ThreadStart(this.InitTimer));
t.IsBackground = true;
t.Start();
} // OnStart
protected override void OnStop()
{
timer.Enabled = false;
} // OnStop
private void InitTimer()
{
timer = new System.Timers.Timer();
// Add the timer event
timer.Elapsed += new ElapsedEventHandler(timerTick);
// Set the interval
double timeInSeconds = 6.0;
timer.Interval = (timeInSeconds * 1000);
timer.Enabled = true;
} // InitTimer()
private void timerTick(object sender, EventArgs e)
{
// CRM connection stuffhere
} // timerTick
}
}
Then the following in the Service1.Designer.cs
namespace FeedManagementService
{
partial class Service1
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.components = new System.ComponentModel.Container();
this.ServiceName = "Feed Management Service";
this.CanPauseAndContinue = true;
} // InitializeComponent()
#endregion
}
}
And lastly the following in ProjectInstaller.cs
namespace FeedManagementService
{
[RunInstaller(true)]
public partial class ProjectInstaller : System.Configuration.Install.Installer
{
public ProjectInstaller()
{
ServiceProcessInstaller process = new ServiceProcessInstaller();
process.Account = ServiceAccount.LocalSystem;
ServiceInstaller serviceAdmin = new ServiceInstaller();
serviceAdmin.StartType = ServiceStartMode.Manual;
serviceAdmin.ServiceName = "Service1";
serviceAdmin.DisplayName = "Feed Management Service";
Installers.Add(process);
Installers.Add(serviceAdmin);
}
}
}
After a lot of investigation and fixing a whole bunch of "problems" which turned out to be nothing to do with the issue, I discovered that I needed the following in the Main() method of the service;
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
As a result of adding this everything seems to work perfectly now, the service starts as expected.
It seems you OnStart() method is not returnig within the allowed timeout. Does the message appears at once, or does it take some 30 seconds to show up? Does your CRM Connection Stuff(tm) takes a while to run?
A longshot: do you use any Windows.Forms stuff in your app? These should not be used on a service, and can interact in strange and mysterious ways.
I encountered the same issue and was not at all sure how to resolve it. Yes this occurs because an exception is being thrown from the service, but there are a few general guidelines that you can follow to correct this:
Check that you have written the correct code to start the service:
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new WinsowsServiceToRun()
};
ServiceBase.Run(ServicesToRun);
You need to ensure that there is some kind of infinite loop running in the class WinsowsServiceToRun
Finally, there may be some code which is not logging anything and closing the program abruptly (which was the case with me), in this case you will have to follow the old school of debugging which needed to write a line to a source (text/db/wherever). What I faced was that since the account running the service was not "Admin", the code was just falling off and not logging any exceptions in case it was trying to write to "Windows Event Log" even though the code was there to log exceptions. Admin privilege is actually not needed for logging to Even Log but it is needed to define the source. In case source of the event is not already defined in the system and the service tries to log it for the first time without admin privilege it fails. To solve this follow below steps:
Open command prompt with admin privilege
Paste the command : eventcreate /ID 1 /L APPLICATION /T INFORMATION /SO <> /D "<>"
Press enter
Now start the service
Related
Apologies ahead of time if I did not indent my code properly, this is my first post. So my end goal is to create a Windows Service that watches events for when a notepad.exe process is started and in response launches mspaint.exe. This is my first time working with Windows Services but I've been able to get this code to work as a Console Application and as the Windows Service while in debug mode. However, whenever I go to install it and test as a release, it installs fine and starts up with no problem but when I launch notepad.exe nothing happens.
**MyNewService.cs**
public MyNewService()
{
InitializeComponent();
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory +"Initialized.txt");
}
public void OnDebug()
{
OnStart(null);
}
protected override void OnStart(string[] args)
{
WqlEventQuery query = new WqlEventQuery("__InstanceCreationEvent", new TimeSpan(0, 0, 1), "TargetInstance isa \"Win32_Process\"");
ManagementEventWatcher watcher = new ManagementEventWatcher(query);
watcher.EventArrived += new EventArrivedEventHandler(watcher_EventArrived);
watcher.Start();
}
protected override void OnStop()
{
System.IO.File.Create(AppDomain.CurrentDomain.BaseDirectory + "OnStop.txt");
}
static void watcher_EventArrived(object sender, EventArrivedEventArgs e)
{
string instanceName = ((ManagementBaseObject)e.NewEvent["TargetInstance"])["Name"].ToString();
if (instanceName.ToLower() == "notepad.exe")
{
Process.Start("mspaint.exe");
}
}
}
**Main Program**
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main(string[] args)
{
#if DEBUG
MyNewService myService = new MyNewService();
myService.OnDebug();
System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
#else
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new MyNewService()
};
ServiceBase.Run(ServicesToRun);
#endif
}
}
SOLVED:
Established that the Service does in fact work. The problem was that it runs as localSystem once installed which only does background services and does not have access to the visible desktop. It was launching the paint.exe in invisible mode. See link below:
https://www.reddit.com/r/csharp/comments/5a5uof/advice_managementeventwatcher_on_a_windows/
I want to make a process/system that should be in a running state constantly and execute a specific function at a specific time period.
For example, if I want the system to send an email to a specific address every week then what should I do?
Running always: go for Windows service
For periodic things: go for timers
So have a Windows service which maintains a timer set to trigger at the required interval and do whatever you need there.
You can use open-source Quartz.NET scheduler(http://www.quartz-scheduler.net/), which can trigger your jobs at specified times and intervals. My suggestion is to host the scheduler job in Windows service.
Here is my example, for some tasks it's ok.
public class Timer : IRegisteredObject
{
private Timer _timer;
public static void Start()
{
HostingEnvironment.RegisterObject(new Timer());
}
public Timer()
{
StartTimer();
}
private void StartTimer()
{
_timer = new Timer(BroadcastUptimeToClients, null, TimeSpan.FromSeconds(0), TimeSpan.FromMilliseconds(100));
}
private void BroadcastUptimeToClients(object state)
{
//some action
}
public void Stop(bool immediate)
{
//throw new System.NotImplementedException();
}
}
In Global.asax
Timer.Start();
In your case I will agree with # Arsen Mkrtchyan - use OS scheduler.
If you would like to use windows service, here is how would look your service:
partial class MyService
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
private Timer _watcherTimer = new System.Timers.Timer();
private static Logger logger = LogManager.GetCurrentClassLogger();
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = "MyService";
this._watcherTimer.Interval = 6000;
this._watcherTimer.Enabled = false;
this._watcherTimer.Elapsed += new System.Timers.ElapsedEventHandler(this.Timer_Tick);
}
#endregion
}
partial class MyService : ServiceBase
{
public MyService()
{
try
{
InitializeComponent();
}
catch (Exception e)
{
logger.Error("Error initializing service",e);
Stop();
}
}
protected override void OnStart(string[] args)
{
_watcherTimer.Enabled = true;
logger.Info("Service has started at " + DateTime.UtcNow.ToLongDateString());
}
protected override void OnStop()
{
logger.Info("Service has stopped at " + DateTime.UtcNow.ToLongDateString());
}
private void Timer_Tick(object sender, ElapsedEventArgs e)
{
logger.Info("Timer Tick");
}
}
Installer:
[RunInstaller(true)]
public class WindowsServiceInstaller : Installer
{
/// <summary>
/// Public Constructor for WindowsServiceInstaller.
/// - Put all of your Initialization code here.
/// </summary>
public WindowsServiceInstaller()
{
var serviceProcessInstaller =
new ServiceProcessInstaller();
var serviceInstaller = new ServiceInstaller();
//# Service Account Information
serviceProcessInstaller.Account = ServiceAccount.LocalSystem;
serviceProcessInstaller.Username = null;
serviceProcessInstaller.Password = null;
//# Service Information
serviceInstaller.DisplayName = "MY SERVICE DISPLAY NAME";
serviceInstaller.Description = "MY SERVICE DESCRIPTION";
serviceInstaller.StartType = ServiceStartMode.Automatic;
//# This must be identical to the WindowsService.ServiceBase name
//# set in the constructor of WindowsService.cs
serviceInstaller.ServiceName = "MyService";
Installers.Add(serviceProcessInstaller);
Installers.Add(serviceInstaller);
}
}
Run this with .bat
static class Program
{
static void Main(string[] args)
{
if (args.Length > 0)
{
//Install service
if (args[0].Trim().ToLower() == "/i")
{ System.Configuration.Install.ManagedInstallerClass.InstallHelper(new[] { "/i", Assembly.GetExecutingAssembly().Location }); }
//Uninstall service
else if (args[0].Trim().ToLower() == "/u")
{ System.Configuration.Install.ManagedInstallerClass.InstallHelper(new[] { "/u", Assembly.GetExecutingAssembly().Location }); }
}
else
{
var servicesToRun = new ServiceBase[] { new MyService() };
ServiceBase.Run(servicesToRun);
}
}
}
install.bat
#ECHO OFF
REM Prevent changing current directory when run bat file as administrator on win7
#setlocal enableextensions
#cd /d "%~dp0"
REM The following directory is for .NET 4.0
set DOTNETFX4=%SystemRoot%\Microsoft.NET\Framework\v4.0.30319
set PATH=%PATH%;%DOTNETFX4%
echo Installing WindowsService...
echo "%CD%\WindowsService\Service\bin\Debug\Service.exe"
echo ---------------------------------------------------
InstallUtil /i "%CD%\WindowsService\Service\bin\Debug\Service.exe"
echo ---------------------------------------------------
echo Done.
set /p DUMMY=Hit ENTER to continue...
unistall.bat
#ECHO OFF
REM Prevent changing current directory when run bat file as administrator on win7
#setlocal enableextensions
#cd /d "%~dp0"
REM The following directory is for .NET 4.0
set DOTNETFX4=%SystemRoot%\Microsoft.NET\Framework\v4.0.30319
set PATH=%PATH%;%DOTNETFX4%
echo Installing WindowsService...
echo ---------------------------------------------------
InstallUtil /u "%CD%\WindowsService\Service\bin\Debug\Service.exe"
echo ---------------------------------------------------
echo Done.
set /p DUMMY=Hit ENTER to continue...
my folder hierarchy:
install.bat
uninstall.bat
service-project-folder
packages
project-folder
.sln file
By making use of ReactiveExtensions you could use the following code if you were interested in doing something as simple as printing to the console as in your currently on hold question here https://stackoverflow.com/questions/30473281/how-to-print-a-string-in-c-sharp-after-every-1-minute-using-timer. You can add Reactive Extensions by adding Rx-Main via NuGet.
using System;
using System.Reactive.Linq;
namespace ConsoleApplicationExample
{
class Program
{
static void Main()
{
Observable.Interval(TimeSpan.FromMinutes(1))
.Subscribe(_ =>
{
Console.WriteLine(DateTime.Now.ToString());
});
Console.WriteLine(DateTime.Now.ToString());
Console.ReadLine();
}
}
}
I am learning window service from msdn link :
http://msdn.microsoft.com/en-us/library/zt39148a(v=vs.110).aspx
I have properly created , install first Time ....when I try to start it from Service.msc ..it is throwing Error :
Error 1053 service didnot respond to start or control request
this is my Code :
public partial class ASMSService : ServiceBase
{
private Timer myTimer;
TimeSpan setTime;
private DateTime previousDate;
private DateTime todaysDate;
public ASMSService()
{
InitializeComponent();
if (!System.Diagnostics.EventLog.SourceExists("MySource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource", "MyNewLog");
}
eventLog1.Source = "MySource";
eventLog1.Log = "MyNewLog";
}
protected override void OnStart(string[] args)
{
myTimer = new System.Threading.Timer(new TimerCallback(TimerAction1));
SetTimer(11, 07, 00);
}
protected override void OnStop()
{
}
private void SetTimer(int hours, int minutes, int seconds)
{
todaysDate = DateTime.Today;
previousDate = todaysDate.AddDays(-1);
setTime = todaysDate.AddHours(hours).AddMinutes(minutes).AddSeconds(seconds).TimeOfDay; ;
}
private void TimerAction1(object e)
{
//some Code
}
}
this is design Code
partial class ASMSService
{
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.IContainer components = null;
/// <summary>
/// Clean up any resources being used.
/// </summary>
/// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
protected override void Dispose(bool disposing)
{
if (disposing && (components != null))
{
components.Dispose();
}
base.Dispose(disposing);
}
#region Component Designer generated code
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
this.eventLog1 = new System.Diagnostics.EventLog();
((System.ComponentModel.ISupportInitialize)(this.eventLog1)).BeginInit();
//
// ASMSService
//
this.ServiceName = "ASMSService";
((System.ComponentModel.ISupportInitialize)(this.eventLog1)).EndInit();
}
#endregion
private System.Diagnostics.EventLog eventLog1;
}
this is Program class:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new ASMSService()
};
ServiceBase.Run(ServicesToRun);
}
}
I have read similar posts on this ..Some posts suggest to install microsoft Patch ..Other suggest the object created should be disposed properly ..I also tried to do that in Onstop method..But it is not working ..Some posts suggest that ServiceBase.Run() method should be called in Main() method ...it is also present in My code
Please Suggest
I can see one great problem with the ASMSService's timer:
It is created :
myTimer = new System.Threading.Timer(new TimerCallback(TimerAction1));
But it is never started:
private void SetTimer(int hours, int minutes, int seconds)
{
todaysDate = DateTime.Today;
previousDate = todaysDate.AddDays(-1);
setTime = todaysDate.AddHours(hours).AddMinutes(minutes).AddSeconds(seconds).TimeOfDay; ;
// You have set the setTime field, otherwise the timer will still have the infinite dueTime and interval - it is not running at all
// You should call SetChange method to start it.
this.mytimer.SetChange(0, (Int64)setTime.ToMilliseconds());
}
SetChange method is required to start the timer if you use the simplest constructor
You may also want to read the following links, they are dealing with similar situations and provide few insights to consider:
Windows service with timer
System.Threading.Timer Not Starting?
At the moment I'm developing a series of Windows services in C#, that use a timer (from System.Timers) to poll the machine they are running on and report stats to a remote listener (remote machine hosts a WCF data service).
The setup is as follows: I have a class that wraps System.Timers.Timer with additional functionality, accepting a generic event handler to be fired when the timer elapses and log information:
public class GenericPoller
{
private EventLog _log;
private string _componentName;
private System.Timers.Timer _timer;
public GenericPoller
(
double interval,
System.Timers.ElapsedEventHandler handler,
EventLog log,
string componentName
)
{
_componentName = componentName;
_log = log;
_timer = new System.Timers.Timer();
_timer.Interval = interval;
_timer.AutoReset = true;
_timer.Enabled = false;
_timer.Elapsed += handler;
}
public void StartPolling()
{
try
{
_timer.Enabled = true;
_log.WriteEntry
(
"Timer started for component '" + _componentName
+ "', with " + _timer.Interval + "ms interval."
);
}
catch
{
_log.WriteEntry("Failed to start timer for component '" + _componentName + "'.");
}
}
public void StopPolling()
{
try
{
_timer.Enabled = false;
_log.WriteEntry("Timer stopped for component '" + _componentName + "'.");
}
catch
{
_log.WriteEntry("Failed to stop timer for component '" + _componentName + "'.");
}
}
}
Any one of the services I'm implementing creates a GenericPoller in their constructor, and in the OnStart method I invoke StartPolling via a separate thread to consume as little time as possible inside this method. The service class looks roughly like this:
public partial class CPUMonitor : ServiceBase
{
private GenericPoller _poller;
Thread _thread;
public CPUMonitor()
{
InitializeComponent();
_poller = new GenericPoller
(
HardwareMonitorCommon.Instance.DefaultPollingInterval,
PollCPU,
EventLog,
"CPUMonitor"
);
}
protected override void OnStart(string[] args)
{
_thread = new Thread(new ThreadStart(_poller.StartPolling));
_thread.Start();
}
protected override void OnStop()
{
_poller.StopPolling();
_thread.Join();
}
private void PollCPU(object sender, System.Timers.ElapsedEventArgs e)
{
Code to aqcuire CPU stats and report to WCF data service...
}
}
I install the services with the installutil.exe command.
The services will sometimes fail to start within the allotted time (error 1053), but there doesn't seem to be any pattern to this problem. Failure to start is about 4 attempts out of 10.
I simply can't understand why this happens. The System/Application event log doesn't report any errors or exceptions from the service processes, and I can't figure out why a timeout would occur if all the "heavy lifting" is taking place in a separate thread.
I'm in no way a pro/expert at writing multithreaded code, so I fully expect to be doing something wrong...I just can't see what it is...
EDIT: the Main method remains in the automatically generated Program.cs file, and I only modified it to add the components that will be run:
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new CPUMonitor(),
new MemoryMonitor()
};
ServiceBase.Run(ServicesToRun);
}
}
I have the following code for a windows service project. I have successfully built it and installed it. When I start it I get an event started in the event log. However, I never get the event for "In Onstart" any idea why this is going on?
namespace ADServiceCarlos
{
public partial class ADServiceCarlos : ServiceBase
{
public ADServiceCarlos()
{
InitializeComponent();
this.AutoLog = true;
if (!System.Diagnostics.EventLog.SourceExists("MySource"))
{
System.Diagnostics.EventLog.CreateEventSource(
"MySource","MyNewLog");
}
eventLog1.Source = "MySource";
eventLog1.Log = "MyNewLog";
}
protected override void OnStart(string[] args)
{
eventLog1.WriteEntry("In OnStart");
}
protected override void OnStop()
{
}
}
}
OK, so this may solve your problem. It's hard to tell exactly without being able to see all your code, but read this - more specifically the "caution" part.
Do not use the constructor to perform processing that should be in
OnStart. Use OnStart to 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. If OnStop releases resources
allocated in the constructor rather than in OnStart, the needed
resources would not be created again the second time the service is
called.
So everything you are doing to initialise the event log in your constructor should be moved to the OnStart event. This will ensure it is create properly each time the service start, which means you should be able to log your OnStart event correctly (providing you do it after initialisation)
Based on what #musefan posted, here is an example. I had to move everything out of the constructor completely.
public class ServiceMain : System.ServiceProcess.ServiceBase
{
public const string SERVICE_NAME = "ServiceName";
/// <summary>
/// Required designer variable.
/// </summary>
private System.ComponentModel.Container components = null;
public ServiceMain()
{
// This call is required by the Windows.Forms Component Designer.
InitializeComponent();
}
/// <summary>
/// Required method for Designer support - do not modify
/// the contents of this method with the code editor.
/// </summary>
private void InitializeComponent()
{
components = new System.ComponentModel.Container();
this.ServiceName = SERVICE_NAME;
this.CanPauseAndContinue = true;
}
static void Main()
{
//Log all unhandled exceptions
AppDomain.CurrentDomain.UnhandledException += UnhandledExceptionTrapper;
System.ServiceProcess.ServiceBase[] ServicesToRun;
ServicesToRun = new System.ServiceProcess.ServiceBase[] { new ServiceMain() };
System.ServiceProcess.ServiceBase.Run(ServicesToRun);
}
/// <summary>
/// Clean up any resources being used.
/// </summary>
protected override void Dispose(bool disposing)
{
if (disposing)
{
if (components != null)
components.Dispose();
}
base.Dispose(disposing);
}
/// <summary>
/// Set things in motion so your service can do its work.
/// </summary>
protected override void OnStart(string[] args)
{
//Do your stuff here
}
static void UnhandledExceptionTrapper(object sender, UnhandledExceptionEventArgs e)
{
Environment.Exit(1);
}
}