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
- Open Visual Studio 2013 and create an empty Sharepoint project. Give the working URL to the box, then select Farm Solution and click Finish.
- 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.
Now it would look something like this:
As you may see, when adding data leave “CompletedHours
” column empty because that’s the column we are going to fill by the TimerJob
.
- Now come back to the Visual Studio project and add a new class to it.
- Refer to the below namespaces:
using Microsoft.SharePoint.Administration;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Utilities;
- Now add those constructors and the "
Execute
" method to it as shown below:
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();
}
}
}
}
}
}
}
- Now add a feature to the solution.
- 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
.
- Right-Click on the added feature and add Event Receiver.
- Open the eventReceiver CS file and place the following code:
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;
}
}
}
- 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:
- 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.
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
- 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”.
- 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.
Special Note
If you modify the code and you need to deploy the code again, you need to follow these steps:
- Go to Central Administration and select Manage features from the ribbon bar.
- Locate the feature and deactivate it and refresh the site.
- Open your Services and locate “
SharePointTimerService
”. Right-click and select restart. - Then go back to your code and deploy your solution.
- 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.