Creating windows service in C# is really easy but when we need to create first time we face many problems so in this post we will try to learn everything about window service. In this article we will create a windows service which will run after a particular interval, and time should be configurable and code to write log in a text file as well as send email if there is any error to execute the required method.
Let’s start creating it, we will use Visual Studio 2010 and C# language for it
It will create two files program.cs and service1.cs Open program.cs file and it created following lines of code, we don’t need anything here
static class Program
{
/// <summary>
/// The main entry point for the application.
/// </summary>
static void Main()
{
ServiceBase[] ServicesToRun;
ServicesToRun = new ServiceBase[]
{
new Service1()
};
ServiceBase.Run(ServicesToRun);
}
}
Now open service1.cs file and click on “Click here to switch to code view”. Here is the default code generated by visual studio
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
}
protected override void OnStop()
{
}
}
We will come here back and add required code but before that let’s add a app.config file to keep our configurable items. Right click on solution and select Add > New Items, in open window select General > Application Configuration File, it will create a very basic app.config file. Add following line
<connectionStrings>
<add name="connectionString"
connectionString="Data Source=sqlServer1;
Initial Catalog=Northwind;
Persist Security Info=True;
User ID=userid;Password=mypassword"
providerName="System.Data.SqlClient" />
</connectionStrings>
<appSettings>
<add key="ServiceInterval" value="10"/>
</appSettings>
In appSetting I added here a key “ServiceInterval” which we will use to set the service loop interval say 10 minute Now let’s back to our Service1.cs file and add some global variables
// Add a time to run service after some interval
private System.Timers.Timer serviceTimer = new System.Timers.Timer();
private DateTime _workStartTime = DateTime.MinValue;
private UInt32 _interval = 60000; // 1 minute = 60, 000 milisecond
private uint _serviceInterval =
Convert.ToUInt32(ConfigurationManager.AppSettings.Get("ServiceCheckInterval"));
In constructor add following after InitializeComponent
_interval = _interval * _serviceInterval;
It will set the service repeater interval by using _interval variable which we set globally for 1 minute and then multiply it by _serviceInterval which we set in our config file to make it configurable.
Now time to write code for our OnStart method, Add following lines of code to OnStart method
protected override void OnStart(string[] args)
{
try
{
_workStartTime = DateTime.MinValue;
serviceTimer.Elapsed += new System.Timers.ElapsedEventHandler(serviceTimer_Elapsed);
serviceTimer.Interval = _interval;
CommonService.LogError("Service started successfully!");
serviceTimer.Enabled = true;
}
catch (Exception ex)
{
CommonService.LogError(string.Format("{0}{1}{2}", ex.Message,
Environment.NewLine, ex.InnerException));
}
}
Here we set _workStartTime to datetime's minimum value which we will use to judge whether service is executing previous task or is in ideal state. Once we will start executing our method we will set this variable to current date time and once finish we will again re-set it to minimum value of date time to indicate our service is ideal.
Here we also created a timer elapsed even handler and enable the timer so it can call our method after our defined interval, also we added code in catch to log every error on starting the service.
public void serviceTimer_Elapsed(object source, ElapsedEventArgs e)
{
//Check if service is ideal or processing previous task
if (this._workStartTime != DateTime.MinValue) return;
try
{
//Assign current time to indicate service is busy
this._workStartTime = DateTime.Now;
/*
Call those methods which you want to do on some interval like database update
image linking or any other task
*/
//Set minimum time to indicate now service is ideal
_workStartTime = DateTime.MinValue;
}
catch (System.Exception ex)
{
_workStartTime = DateTime.MinValue;
String err = String.Format("{0}{1}{0}{2}{0}{3}", Environment.NewLine,
ex.Message, ex.InnerException, ex.StackTrace);
CommonService.LogError(err);
}
}
Now we need to write code for our final method OnStop, we can add here some code which can send email or log service stop message in our log file so we can understand when service was stopped.
protected override void OnStop()
{
CommonService.LogError("Service stopped now at!");
}
We complete our coding part but not discussed how to add installer to this service so let's discuss it
It will add an installer to our service.
We used CommonService.LogError method to log error, here is code for that method
public static void LogError(String msg)
{
try
{
String LogFile = String.Format("{0}\\errorlog.txt", Application.StartupPath);
if (LogFile != "")
{
String Message = String.Format(
@"{0}====================== {1} ====================={0}{2}{0}"
, Environment.NewLine, DateTime.Now, msg);
byte[] binLogString = Encoding.Default.GetBytes(Message);
System.IO.FileStream logFile = new System.IO.FileStream(LogFile,
System.IO.FileMode.OpenOrCreate,
System.IO.FileAccess.Write,
System.IO.FileShare.Write);
logFile.Seek(0, System.IO.SeekOrigin.End);
logFile.Write(binLogString, 0, binLogString.Length);
logFile.Close();
}
}
catch { ; }
}
To create windows service setup check my other post Create windows service setup in visual studio
![]() |
Having 13+ years of experience in Microsoft Technologies (C#, ASP.Net, MVC and SQL Server). Worked with Metaoption LLC, for more than 9 years and still with the same company. Always ready to learn new technologies and tricks.
|
By Ali Adravi On 30 Apr, 13 Viewed: 8,610 |
Polymorphism is derived from two Latin words, 1. Poly means many 2. Marphose means forms. By using inheritance, a class can be used as many types, say we have a Person which may be a Professor, may be a Student, may be Clerk. So in this article we will see some example of Polymorphism. When we... By Hamden On 01 Jun 2013 Viewed: 4,548
C# the language, right from the very beginning is always supported covariance and contravariance but in most simple scenario, now in C# 4.0 we have full support of covariance and contravariance in all circumstances, generic interface and generic delegates, other C# types already support from first... By Ali Adravi On 29 Mar 2013 Viewed: 4,977
In C# there are different data type and they use some default value when we declare a variable. When we define a variable of type int or Int32 say int score; so what is the value of score, will it be null or zero, in the same way if we create a variable of type string/String what value it holds... By Ali Adravi On 27 Mar 2013 Viewed: 2,599
An enumeration type (also known an enumeration or an enum) provides an efficient way to define a set of named integral constants that may be assigned to a variable to make programming clear, understandable and manageable. There are ways of using, like how to use enum in switch and case statement,... By Hamden On 27 Mar 2013 Viewed: 4,525
When we have var which dynamically holds any type or value so why we need dynamic type, what are the differences and situations where we can use dynamic rather than var, there were some question in my mind so I explored more which I want to share here. There are two things, static type and... By Nathan Armour On 26 Mar 2013 Viewed: 3,204