SharePoint Pals
 | Sign In
Step by Step procedures to create a Timer Job in SharePoint 2013
by Sathish Nadarajan 25 Jun 2013
Author
SharePoint MVP
Visits   
Today  :   30     Total  :    65577

In this article, we will see how to create a Timer Job step by step in SharePoint 2013. Timer Job, from the beginning of the SharePoint era, plays a vital role in SharePoint Development. Though most of us would have developed ‘n’ Number of timer jobs in SP 2007 as well as SP2010, there are certain changes that happened on the Security aspect of SharePoint 2013 timer job. Let us see them step by step and then there, we will look into the key points.

1. Open the Visual Studio 2012.

2. Click New Project.

3. Select the Empty SharePoint Solution Template.

4. An empty project will be created as below.

clip_image002

5. Right click on the Project and Select New Folder

clip_image004

6. Name the folder as Jobs.

7. Add a class inside Jobs folder.

clip_image006

8. The class will look like this.

   using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Threading.Tasks;    namespace MyNamespace  {   class MyTimer   {     }  }  

9. Modify the class as shown below. i.e., we are going to inherit SPJobDefinition class and make the class as public and create the constructors as shown below.

 using Microsoft.SharePoint.Administration;  using System;  using System.Collections.Generic;  using System.Linq;  using System.Text;  using System.Threading.Tasks;    namespace MYNamespace  {   public class MyTimer : SPJobDefinition   {   HashSet<string> seenUids = new HashSet<string>();     public MyTimer ()   : base()   {     }     public MyTimer (string jobName, SPService service, SPServer server, SPJobLockType targetType)   : base(jobName, service, server, targetType)   {     }     public MyTimer (string jobName, SPWebApplication webApplication, string strUrl)   : base(jobName, webApplication, null, SPJobLockType.ContentDatabase)   {   this.Title = jobName;   }       public override void Execute(Guid ContentDatabaseID)   {   try   {       }   catch (Exception ex)   {     }   }   }  }

10. Now the timer class is ready. Now we need to deploy this timer in to the SharePoint farm. To do this, we need to create a Feature and a FeatureReceiver. On the Activation of the Feature, we are going to add this timer into our SharePoint Farm.

11. Add a feature by right click on the Features folder.

clip_image008

12. Name the Feature and give the Description appropriately. Make the Scope of the Feature as Webapplication.

clip_image010

13. The above point is the key factor in SP2013. Because, in SP2010, we can give the scope as SiteCollection and can update the WebApplication properties from the FeatureReceiver. To do that, we have to run the power shell script to get rid of “Access Denied” Exception. To be more precise, Whenever, we are trying to update any of the WebApplication Properties, sharepoint will throw an “Access Denied” Exception. Please have a look into the below piece of code inside the FeatureActivated Event.

   public override void FeatureActivated(SPFeatureReceiverProperties properties)  {   try   {   SPSecurity.RunWithElevatedPrivileges(delegate()   {   SPWebApplication webapplication = properties.Feature.Parent as SPWebApplication;     if (webapplication.Properties.Contains("SiteURL"))   webapplication.Properties.Remove("SiteURL");     webapplication.Properties.Add("SiteURL", "http://MysitecollectionURL");   webapplication.Update();     foreach (SPJobDefinition job in webapplication.JobDefinitions)   {   if (job.Name == "SathishSampleTimer")   job.Delete();   }         Mytimer timer = new Mytimer("SathishSampleTimer", webapplication, "http:// MysitecollectionURL ");     SPDailySchedule schedule = new SPDailySchedule();     schedule.BeginHour = 01;   schedule.BeginMinute = 00;   schedule.BeginSecond = 00;     schedule.EndHour = 01;   schedule.EndMinute = 01;   schedule.EndSecond = 00;     timer.Schedule = schedule;   timer.Update();   });   }   catch (Exception ex)   {     }  }  

On the WebApplication.Update(), Usually we will get an “Access Denied” Exception. To overcome this, either from C# or through the PowerShell Script, we will rectify them on the SharePoint 2010. The c# or PowerShell Script is as follows.

   if (SPWebService.ContentService.RemoteAdministratorAccessDenied == true)  {   SPWebService.ContentService.RemoteAdministratorAccessDenied = false;   SPWebService.ContentService.Update(true);  }  

Or by using the following powershell script, we can get rid of the Access Denied Exception in SharePoint 2010.

   function Set-RemoteAdministratorAccessDenied-False()  {   [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint") > $null   [System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration") > $null     # get content web service   $contentService = [Microsoft.SharePoint.Administration.SPWebService]::ContentService   # turn off remote administration security   $contentService.RemoteAdministratorAccessDenied = $false   $contentService.Update()  }    Set-RemoteAdministratorAccessDenied-False  

14. Why we are going for PowerShell is, even sometimes, SPWebService.ContentService.Update(true); will also throw access denied exception.

15. But in SP 2013, even after doing the above also, I was getting “Access Denied” exception. After spending couple of hours, identified that, the Security in SP 2013 has been increased and only, if the WebApplication Scoped Feature can make any changes on the WebApplication Level. Because, many user will be having access to different site collections. When they modify any of the Feature on any SiteCollection, it should not affect the WebApplication. For that reason, SP 2013 gives way only for the WebApplication scoped Feature to access any of the WebApplication property.

16. Hence, now we are ready to deploy our solution into the SharePoint Environment.

17. One more important thing, is for our understanding, make the default activation of the feature as false.

clip_image012

18. Even immediate below, “Always Force Install”, make it as true.

19. Make sure that on the Feature DeActivation, we are deleting the timer job. This will help us to clean the timer job, whenever the Feature gets deactivated.

 public override void FeatureDeactivating(SPFeatureReceiverProperties properties)  {   try   {   SPSecurity.RunWithElevatedPrivileges(delegate()   {   SPWebApplication webapplication = properties.Feature.Parent as SPWebApplication;     foreach (SPJobDefinition job in webapplication.JobDefinitions)   {   if (job.Name == "SathishSampleTimer")   job.Delete();   }   });   }   catch (Exception ex)   {     }  }

20. Now, we are ready for the deployment.

clip_image014

21. Then go to the Central Administration. Manage Web Application. Select your Web Application on which the Solution has been Deployed. Select Manage Features.

clip_image016

22. You will get the below screen.

clip_image018

23. Activate the feature.

24. On the Activation, we can see our timer job get listed on the Monitoring->Review Job Definitions.

clip_image020

25. Now, another challenging issue, regarding the debugging of Timer Job. We need to attach with the process OWSTimer.exe to debug the timer job. On the Execution, Execute will be the first method get invoked. Put a break point over there and attach to OWSTimer.exe.

26. Sometimes, we will get a strange exception like “UnAble to evaluate Expression” while debugging the timer job. This is happening because of the cross threads between the w3wp.exe and OWSTimer.exe. To overcome this, restart the IIS. This will clear the w3wp process. Then come to Services.msc and restart the SharePoint Timer Services. This will restart the OWSTimer and make sure that the latest dll is referred with the Debugger.

clip_image022

27. Whenever you make any code changes and re-deploy the solution, restart the Timer Service too. This will reduce your debugging time with strange issues. J.

28. Another Important thing to be noted as Deployment Target. Whenever you want to deploy your timer job into WebApplication scope, you will get an “Assembly cannot be loaded” loaded exception. This is because of whenever you are trying to deploy a timer, the timer will search for the DLLs from the GAC and not from the Bin of the Web Application. Hence, always, the timer job should be deployed on the GlobalAssemblyCache.

With this, the sample timer job has been created and the tips and tricks to debug and fix the errors were discussed. If you find, I missed anything or anything is wrong, please feel free to comment on that.

Download SourceCode
blog comments powered by Disqus

SharePoint Pals

Pals
SharePoint Pals, a community portal for SharePoint developers, Administrators and End Users. Let's join hands and share the point together.
Read this on mobile

Training

Angular Js Training In Chennai
Advanced Angular Js training with real world developer scenarios
Angular Js, Web Api and Ionic for .Net Developers
All in one client side application development for .Net developers
Angular Js For SharePoint Developers
Get ready for the future. Its no more just C#

Get Connected

SharePoint Resources

SharePoint 2013 and 2010 Web Parts
Free Web Parts with Source Code for SharePoint Community




SharePoint 2013 Books and Tutorials
Collection of free SharePoint 2013 books and tutorials (eBooks, pdfs)

Supported By

Contribute your article and be eligible for a one month Free Subscription for Plural Sight. The Author of the most popular New Article (published in the previous month) will be awarded with a Free One month Plural Sight Subscription. Article can be sent to articles@sharepointpals.com in a word document.

Related Resources

Recent Tweets

Twitter January 15, 00:25
How To Enable Target Value And Actual Value In #D3 Gauge Chart https://t.co/VxSi4QnNrC

Twitter January 15, 00:24
How To Open #SharePoint List Hyperlink Column In Modal #Popup Window https://t.co/EQ7HkoZDkX

Twitter January 15, 00:24
Quick Introduction To #Asp.NetCore And It’s Features https://t.co/zAXObHCFpH

Twitter January 15, 00:22
How To Configure #PerformancePoint Services To Use Secure Store In #SharePoint 2013 https://t.co/LEwnUoI7EY

Twitter January 15, 00:21
How To Block Or Disable #Office365 Services https://t.co/Yvp2VPFIRP

Follow us @SharePointPals
Note: For Customization and Configuration, CheckOutRecent Tweets Documentation