Category Archives: Windows services

Creating a setup project for a windows service using VS2010

This post assumes that you ar familiar with creating windows services using VS2010 and that You have added an installer to the design view of your service as described in this MSDN article.

Assuming that you have an open solution containing your windows service – do the following to add and configure a setup project:

  1. Right click your solution and choose “add” –> “new project”.
  2. From the menu on the left choose “installed templates” –> “other project types” –> “Setup and deployment” –> Visual studio installer.
  3. Select “Setup project” and put in a suiting name for the project

    add new project screenshot

    add new project screenshot

  4. Setup project screenshot
  5. add project output group

    add project output group

  6. Custom actions

    Custom actions

Execute job within a Windows Service at a certain time

Quite often I am asked to create a job to run within a windows service – the following demands applies:

  • A Windows Service is needed since the demands for applying a schedule is not met by the “Scheduled Tasks” features from Windows. Due to that a Console App is ruled out.
  • The job routine must be executed at a certain time – this must be configurable.
  • When the job routine has been executed a schedule must be started – this must be configurable.

To accomplish this we will use:

  • an app.config file to hold our configuration
  • Two Timers – remember to use System.Threading.Timer rather than the System.Windows.Forms.Timer

What we need to do is:

  • Create an OnStart event that starts the processing in a separate thread. This is always a good idea since you will avoid start problems if the process your are starting takes some time to finish.
  • Calculate the time from now and until the job is supposed to run. Start a timer with exactly that delay by setting the duetime of the Timer.
  • When the job executes… Create a new timer and set the Period of the Timer to correspond to the wanted schedule.

Here’s an example of one way to accomplish the task:

    1         protected override void OnStart(string[] args)

    2         {

    3             //Start the actual job in a separate thread to avoid timeouts on start

    4             backgroundWorker = new System.ComponentModel.BackgroundWorker();

    5             backgroundWorker.WorkerReportsProgress = false;

    6             backgroundWorker.DoWork += new DoWorkEventHandler(backgroundWorker_DoWork);

    7             backgroundWorker.RunWorkerAsync();

    8         }


   10         void backgroundWorker_DoWork(object sender, DoWorkEventArgs e)

   11         {

   22             //the timer that initilizes that the job is executed for the first time at a certain time

   12             StartInitTimer();

   13         }

Let’s look at the StartInitTimer() method:

   30         ///<summary>

   31         /// Starts the initializing timer. this timer runs once and sets the aplicationlogic to run on the configured schedule

   32         ///</summary>

   33         private void StartInitTimer()

   34         {

   35             //calcuale the delay until the point of starting time

   36             DateTime start = DateTime.Parse(ConfigurationManager.AppSettings[“ImportStartTime”]);

   37             DateTime current = DateTime.Now;

   38             TimeSpan timeBeforeStart;

   39             if (start < current)

   40             {

   41                 //the starttime for today has passed – calculate the start time after midnight

   42                 DateTime midnight = GetMidnight();

   43                 TimeSpan timeBeforeMidnight = midnight.Subtract(current);

   44                 timeBeforeStart = timeBeforeMidnight.Add(new TimeSpan(start.Hour, start.Minute, start.Second));

   45             }

   46             else

   47             {

   48                 timeBeforeStart = start.Subtract(current);

   49             }

   50             //start the timer

   51             initTimer = new System.Threading.Timer(InitTimer_Elapsed, null, timeBeforeStart, new TimeSpan(0, 0, 0)); //setting timespan to -1 milliseconds causes the timer to run once

   52         }


   54         ///<summary>

   55         /// Helper method – Calculates a datetime object for the next coming midnight

   56         ///</summary>

   57         ///<returns></returns>

   58         private DateTime GetMidnight()

   59         {

   60             DateTime midnight = new DateTime(DateTime.Now.Year, DateTime.Now.Month, DateTime.Now.Day, 0, 0, 0);

   61             midnight = midnight.AddDays(1);

   62             return midnight;

   63         }


   65         ///<summary>

   66         /// handles the elapsed event of the imitializing timer

   67         ///</summary>

   68         ///<param name=”sender”></param>

   69         ///<param name=”e”></param>

   70        private void InitTimer_Elapsed(object state)

   71         {

   72             //import is executed one time only in this eventhandler.

   73             try

   74             {

   75                 //Start the schedule

   76                 StartScheduleTimer();

   77                 //perform the job

   78                 DoSomething();


   80             }

   81             catch (Exception ex)

   82             {


   84             }

   85             finally

   86             {

   87                 //dispose the timer object – this timer has done it’s purpose

   88                 initTimer.Dispose();

   89             }


   91         }

  100         private void StartScheduleTimer()

  101         {

  102             //the interval in hours

  103             //                                                                                   s     m    h

  104             int timerInterval = int.Parse(ConfigurationManager.AppSettings[“TimerInterval”]) * 1000 * 60 * 60;

  105             scheduleTimer = new System.Threading.Timer(ScheduleTimer_Elapsed, null, timerInterval, System.Threading.Timeout.Infinite);

  106         }



  109         ///<summary>

  110         /// Every time the timer ticks – the ScheduleTimer_Elapsed method is triggered – the job stuff is being performed here

  111         ///</summary>

  112         ///<param name=”sender”></param>

  113         ///<param name=”e”></param>

  114         private void ScheduleTimer_Elapsed(object state)

  115         {

  116             //reset the timer – set the due/wait time until next event firing

  117             //                                                                                  s     m    h

  118             scheduleTimer.Change(int.Parse(ConfigurationManager.AppSettings[“TimerInterval”]) * 1000 * 60 * 60, System.Threading.Timeout.Infinite);

  119             //perform the job

  120             DoSomething();

  121         }

Service start problem – error 1053

A collegue of mine reported that he experienced difficulties deploying af  .net 4.0 windows service. The installation process went just fine, but when trying to start the service he recieved the following error almost instantly:

Service start problem screenshot

Trying to get a grip on the cause of the error, the OnStart event of the service was left blank – and still the service failed to start.

Usuallly when a service fails to start and return error 1053 almost instantly, it is caused by a reference to an assemmbly which is not properly loaded. In this case only references to .net assemblies were created. Having installed the .net framework 4.0 should make you think that you are homefree – but that’s not necessarily the case. The secret lies in which target framework you choose to build your service on:

 select framework screenshot

In this case the .NET framework 4 was choosen, because some of the assmeblies used, were not included in the default “.NET Framework 4 Client Profile”. On the server where the service was deployed it turned out, that only the .net framework 4 client profile was installed. Now the solution was simple – we just had to install the extended version of the .Net framework.

Problem solved:-)