Click here to Skip to main content
15,884,099 members
Articles / Productivity Apps and Services / Microsoft Office
Tip/Trick

Programmatically create SharePoint Timer Job

Rate me:
Please Sign up or sign in to vote.
4.00/5 (2 votes)
14 May 2015CPOL3 min read 17.7K   2  
How to develop,deploy and debug a simple Timer job application

Introduction

This tip is mainly focusing towards beginners of Sharepoint. You will find the complete step-by-step explanation on how a timer job gets developed, deployed and debugged.

Our scenario is:

Create a TimerJob to run for every 15 minutes and update a List column by calculating how long it has been there by the time the TimerJob runs.

Pre-requisites

As pre-requistes, you must have a working web application created on your farm, if you have no idea how to set a working URL, please refer to my article.

Secondly, you must have a List created on your site and have some data added.

Using the Code

  1. Open Visual Studio 2013 and create an empty Sharepoint project. Give the working URL to the box, then select Farm Solution and click Finish.
  2. Create a list in your SharePoint site (on the browser) and add some values to it.

    My list name is TutorBackUp, and I have TutorID, FirstName and CompleatedHours as columns (all are string columns), apart from the columns I’ve added, SharePoint automatically creates ‘Created’ column alone with many more other columns. Now I have selected that 'Created' column also to display on the list by checking them.

    Image 1

    Now it would look something like this:

    Image 2

    As you may see, when adding data leave “CompletedHours” column empty because that’s the column we are going to fill by the TimerJob.

  3. Now come back to the Visual Studio project and add a new class to it.

    Image 3

  4. Refer to the below namespaces:
    C#
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Utilities;
  5. Now add those constructors and the "Execute" method to it as shown below:
    C#
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;
    using System.Threading.Tasks;
    using Microsoft.SharePoint.Administration;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Utilities;
    
    namespace SecondTimerJob
    {
        public class CalculateRegisteredDays : SPJobDefinition
        {
    
            public CalculateRegisteredDays() : base() { }
    
            public CalculateRegisteredDays(string jobName, SPService service)
                : base(jobName, service, null, SPJobLockType.None)
            {
                this.Title = "Tutor Bakup update Timer";
            }
    
            public CalculateRegisteredDays(string jobName, SPWebApplication webapp)
                : base(jobName, webapp, null, SPJobLockType.ContentDatabase)
            {
                this.Title = "Tutor Bakup update Timer";
            }
    
            public override void Execute(Guid targetInstanceId)
            {
                SPWebApplication webApp = this.Parent as SPWebApplication;
                SPList taskList = webApp.Sites[1].OpenWeb().GetList
                                  ("mysitecollection/mySite/Lists/TutorBackUp");
                if (taskList != null)
                {
                    string convertedTodayDateTime = 
                        SPUtility.CreateISO8601DateTimeFromSystemDateTime(DateTime.Now);
    
                    string qry = "<Where><Lt><FieldRef Name='Created' />
                    <Value IncludeTimeValue='TRUE' Type='DateTime'>" + 
                    convertedTodayDateTime + "</Value></Lt></Where>";
                    SPQuery Query = new SPQuery();
                    Query.Query = qry;
    
                    SPListItemCollection collection = taskList.GetItems(Query);
    
                    foreach (SPListItem item in collection)
                    {
                        int id = int.Parse(item["ID"].ToString());
                        SPListItem modifyItem = taskList.Items.GetItemById(id);
                        if (modifyItem != null)
                        {
                            if (item["CompleatedHours"] == null)
                            {
                                DateTime createdData = Convert.ToDateTime(item["Created"]);
                                var totalHours = (DateTime.Now - createdData).TotalHours;
                                modifyItem["CompleatedHours"] = 
                                "When the Timer trigger it has compleated " + totalHours + " days";
                                modifyItem.Update();
                            }
                        }
                    }
                }
            }
        }
    }
  6. Now add a feature to the solution.

    Image 4

  7. I have renamed it as "UpDateTutorFeature". Double click on it and change the Title, select Scope to WebApplication and in the properties window, make Active Force install and Active on default into TRUE.

    Image 5

  8. Right-Click on the added feature and add Event Receiver.

    Image 6

  9. Open the eventReceiver CS file and place the following code:
    C#
    using System;
    using System.Runtime.InteropServices;
    using System.Security.Permissions;
    using Microsoft.SharePoint;
    using Microsoft.SharePoint.Administration;
    
    namespace SecondTimerJob.Features.UpDateTutorFeature
    {
        [Guid("17e06635-6f9b-4d3c-a64f-d1428f7323fb")]
        public class UpDateTutorFeatureEventReceiver : SPFeatureReceiver
        {
            const string JobName = "Tutor Bakup update Timer";
    
            public override void FeatureActivated(SPFeatureReceiverProperties properties)
            {
                try
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate {
                        SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
                        SPSite site = properties.Feature.Parent as SPSite;
                        DeleteJob(JobName, parentWebApp);
                        CreateJob(parentWebApp);
                    });
                }
                catch (Exception)
                {                
                    throw;
                }
            }
    
            public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
            {
                lock (this)
                {
                    try
                    {
                        SPSecurity.RunWithElevatedPrivileges(delegate() {
    
                            SPWebApplication parentWebApp = 
                                    (SPWebApplication)properties.Feature.Parent;
                            DeleteJob(JobName, parentWebApp);
                        });
                    }
                    catch (Exception ex)
                    {                    
                        throw ex;
                    }
                }
            }
    
            public bool CreateJob(SPWebApplication site) 
            {
                bool jobCreated = false;
    
                try
                {
                    CalculateRegisteredDays job = new CalculateRegisteredDays(JobName, site);
                    SPMinuteSchedule schedule = new SPMinuteSchedule();
                    schedule.BeginSecond = 0;
                    schedule.EndSecond = 59;
                    schedule.Interval = 15;
                    job.Schedule = schedule;
                    job.Update();
                }
                catch (Exception)
                {
                    
                    throw;
                }
                return jobCreated;
            }
    
            public bool DeleteJob(string jobName, SPWebApplication site) 
            {
                bool jobdeleted = false;
                try
                {
                    foreach (SPJobDefinition job  in site.JobDefinitions)
                    {
                        if(job.Name==jobName)
                        {
                            job.Delete();
                            jobdeleted = true;
                        }
                    }
                }
                catch (Exception)
                {
    
                    return jobdeleted;
                }
    
                return jobdeleted;        
            }       
        }
    }
  10. Now you have completed your code. Right-click on the project and click "Deploy". Once the Deploy is successful, go to Central Administrator, select Application Management --> select the site and click Manage Features from the ribbon. If the Deployment is successful, you will be able to locate your feature activated as shown below:

    Image 7

  11. Now to debug your code, go back to Visual Studio and get the “Attach To Process” pop-up and take “OWSTIMER.EXE” and click Attach.

    Image 8

  12. TimerJob has successfully deployed and is fully ready to be debugged. Since the Timer will work in every 15 minutes, you cannot start your debugging immediately. Therefore to debug immediately, you may need to invoke the timer manually. This is only for debug purposes, otherwise the timer job will run on its own.

    Steps to Invoke TimerJob

    Go back to Central Administration --> select “Monitoring” --> Review job definition

    Image 9

  13. This will open all the timer jobs in the farm. To find your timerjob, look for the timer job name you gave on the code. In this case, it's “Tutor Bakup update Timer”.

    Image 10

  14. Once you click on the TimerJob, it will open the below window. From there, Click Run Now and then you will be able to immediately hit the debug points.

    Image 11

Special Note

If you modify the code and you need to deploy the code again, you need to follow these steps:

  1. Go to Central Administration and select Manage features from the ribbon bar.
  2. Locate the feature and deactivate it and refresh the site.
  3. Open your Services and locate “SharePointTimerService”. Right-click and select restart.
  4. Then go back to your code and deploy your solution.
  5. Then attach the “OWSTIMER.EXE” from the Attach to process popup. Now you have deployed the modified code and also your solution is ready to be debugged.

 

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer
Sri Lanka Sri Lanka
Hi
I am a professional developer with a working experience in .NET (VB and C#, WinForms, MVC, Entity Framework, SharePoint), JavaScript, SAP development and SQL Server.

Comments and Discussions

 
-- There are no messages in this forum --