In this SharePoint tutorial, we will discuss what is a timer job in SharePoint. How we can create a timer job in SharePoint 2016/2013 programmatically using Visual Studio?
We will discuss, how to debug SharePoint timer job using visual studio. And also, we will see various SharePoint 2016/2013 Timer Job Schedule Options.
In this SharePoint demo, we will see how we can create a custom timer job in SharePoint 2016 using Visual Studio 2015. But the same way we can create and deploy the timer job to SharePoint 2013 using visual studio 2015/2017 programmatically.
What is a timer job in SharePoint?
In SharePoint, we can use a timer job to execute a task on schedule time. Timer jobs are tasks that usually run at a scheduled time in SharePoint. In a SharePoint timer job, we use the SharePoint server object model code. So we can not develop a timer job for SharePoint Online.
For SharePoint Online, we have to develop web jobs which is an alternative to timer job in SharePoint Online. We can develop timer job for SharePoint 2013/2016/2019 etc using Visual Studio.
Timer jobs are like background processes that do certain tasks and are managed by SharePoint. By default, there are various timer jobs available in SharePoint which you can view from central administration.
Open SharePoint 2016 Central Administration -> Monitoring -> Then under Timer Jobs click on “Review job definitions”. This page will display all the default timer jobs in SharePoint.
How to create a timer job in SharePoint 2016 programmatically (Step by Step)
In this example, the timer job in SharePoint will do the following tasks.
- It will read the items from a SharePoint list.
- Then it will create subsites under the site by using column values from the custom list.
Create a timer job in SharePoint
Follow the below steps to create a timer job in SharePoint 2016 programmatically using Visual Studio.
Open visual studio and then File -> New -> Project…
Then select SharePoint Solution which is under Templates -> Visual C# -> Office/SharePoint. Then choose SharePoint 2016 – Empty Project. Give a name and click on OK.
Then provide a local SharePoint site for debugging and then choose to Deploy as a farm solution.
Now in the next step add a class to the project.
Right-click on the Project -> Add -> New Item… Then choose a class file from Visual C# Items -> Code.
Then the class should inherit from Microsoft.SharePoint.Administration.SPJobDefinition class.
So the class should look like below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SharePoint.Administration;
namespace CustomTimerJob
{
Public class OurCustomTimerJob:SPJobDefinition
{
}
}
After this add three constructors to the class with few parameters and the class now should looks like below:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.SharePoint.Administration;
namespace CustomTimerJob
{
Public class OurCustomTimerJob : SPJobDefinition
{
public OurCustomTimerJob() : base() { }
public OurCustomTimerJob(string jobName, SPService service) :base(jobName, service, null, SPJobLockType.None)
{
this.Title = “Our Custom Timer Job”;
}
public OurCustomTimerJob(string jobName, SPWebApplication webapp) :base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
this.Title = “Our Custom Timer Job”;
}
}
}
Then we need to override the Execute method which will contain our business logic. Now we can add the business logic here in the Execute method.
So here I have a list which has a structure like the below:
Then we have to override the Execute method where we have to keep the business logic. This is the only method where we have to add logic.
public override void Execute(Guid targetInstanceId)
{
string title = string.Empty;
string description = string.Empty;
string url = string.Empty;
string template = string.Empty;
SPWebApplication webapp = SPWebApplication.Lookup(new Uri(“http://mypc:29024”));
SPWeb web = new SPSite(“http://mypc:29024/sites/HydTraining/”).OpenWeb();
SPList olist = web.Lists[“SiteCreationProcessList”];
SPListItemCollection oitem = olist.Items;
foreach (SPListItem item in oitem)
{
title = item[“Title”].ToString();
description = item[“Description”].ToString();
url = item[“WebSiteAddress”].ToString();
template = item[“TemplateSelection”].ToString();
try
{
using (SPSite mySite = new SPSite(“http://mypc:29024/sites/HydTraining/”))
{
using (SPWeb myWeb = mySite.OpenWeb())
{
SPWeb oweb = myWeb.Webs.Add(url, title, description, 1033, template, false, false);
}
}
}
catch (SPException)
{
}
finally
{
}
}
}
The above code will pick items from the list and will create a subsite with the supplied parameters.
Add Feature to the Timer Job in SharePoint
Then right-click on the Features folder and then click on Add Feature. This will add a custom feature to it. You can rename the feature for an appropriate name.
Give a proper Title for your feature. Then set the scope to WebApplication like below:
If you want the feature to be activated by default then you can change Activate On Default property from False to True like below:
Then right-click on the Feature and then click on Add Event Receiver. In the event receiver file, we will add logic to handle the FeatureActivated and FeatureDeactivating method.
In the Feature Activated, We will first delete the existing job and then create a new job. Similarly, in the FeatureDeactivating method, we will simply delete the existing job.
Here we have scheduled the job to run in every 5 minutes. But you can set the time interval according to your requirement.
The full code will look like the below:
using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
namespace CustomTimerJob.Features.OurCustomTimerJobFeature
{
/// <summary>
/// This class handles events raised during feature activation, deactivation, installation, uninstallation, and upgrade.
/// </summary>
/// <remarks>
/// The GUID attached to this class may be used during packaging and should not be modified.
/// </remarks>
[Guid(“f01fcc35-3b30-434a-b43a-fadc69a6fe69”)]
public class OurCustomTimerJobFeatureEventReceiver : SPFeatureReceiver
{
const string JobName = “Site Creation Timer”;
// Uncomment the method below to handle the event raised after a feature has been activated.
public override void FeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
SPSite site = properties.Feature.Parent as SPSite;
DeleteExistingJob(JobName, parentWebApp);
CreateJob(parentWebApp);
});
}
catch (Exception ex)
{
throw ex;
}
}
private bool CreateJob(SPWebApplication site)
{
bool jobCreated = false;
try
{
OurCustomTimerJob job = new OurCustomTimerJob(JobName, site);
SPMinuteSchedule schedule = new SPMinuteSchedule();
schedule.BeginSecond = 0;
schedule.EndSecond = 59;
schedule.Interval = 5;
job.Schedule = schedule;
job.Update();
}
catch (Exception)
{
return jobCreated;
}
return jobCreated;
}
public bool DeleteExistingJob(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;
}
// Uncomment the method below to handle the event raised before a feature is deactivated.
public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
{
lock (this)
{
try
{
SPSecurity.RunWithElevatedPrivileges(delegate ()
{
SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
DeleteExistingJob(JobName, parentWebApp);
});
}
catch (Exception ex)
{
throw ex;
}
}
}
// Uncomment the method below to handle the event raised after a feature has been installed.
//public override void FeatureInstalled(SPFeatureReceiverProperties properties)
//{
//}
// Uncomment the method below to handle the event raised before a feature is uninstalled.
//public override void FeatureUninstalling(SPFeatureReceiverProperties properties)
//{
//}
// Uncomment the method below to handle the event raised when a feature is upgrading.
//public override void FeatureUpgrading(SPFeatureReceiverProperties properties, string upgradeActionName, System.Collections.Generic.IDictionary<string, string> parameters)
//{
//}
}
}
Debugging SharePoint Timer Job
Deploy SharePoint Timer Job
To deploy a SharePoint timer job, right-click on the timer job in visual studio and then click on Deploy. Once it is deployed successfully.
Open SharePoint 2016 central administration, then click on Manage web application which is under Application Management.
Then select the particular web application and then click on Manage Features and you should be able to see our feature which has been published below:
Now to see the timer job, open SharePoint 2016 central administration, then click on Monitoring, and then click on “Review job definitions” which is under Timer Jobs. You can see your custom timer job below:
Click on the timer job to see the details about it.
Once the SharePoint timer job runs successfully, you can see it will create sub-sites like the below:
Debug SharePoint 2016 timer job using Visual Studio
Now, we will discuss, how to debug the timer job in SharePoint 2016 using visual studio 2015/2017. Debugging a timer job is different from a normal farm solution.
To debug the timer job open the visual studio 2015 timer job solution. Click on Debug -> Attach to Process…
Then in the Attach to Process select “OWSTIMER.EXE” and click on Attach. If you did not see the OWSTIMER.EXE process then you can check “Show processes from users” checkbox.
Then in the Attach Security Warning click on the Attach button.
You may get the below message, just wait for the message box to go.
You can give a breakpoint in the Execute method in the Timerjob class. When the timer job scheduled time occurs it will hit the breakpoint. If the breakpoint did not hit then you can restart the timer job service.
For this click on Window + R, then type services.msc. It will open the Services screen. There search for SharePoint Timer Service and click on Restart the service like below:
You can also run the timer job immediately by running the job now.
Open SharePoint central administration, then click on Monitoring and then click on Review job definitions. Then click on the particular timer job and then when the Edit Timer job page will open click on Run Now button like below:
Then the debugger point will hit and you can debug the timer job.
SharePoint 2016 Timer Job Schedule Options
Now, we will see what are the various options to schedule a timer job in SharePoint 2016 or SharePoint 2013 while developing using Visual Studio 2015/2017.
Below are the ways you can schedule a timer job in SharePoint 2016/2013.
Yearly:
SPYearlySchedule yearschedule = new SPYearlySchedule();
yearschedule.BeginMonth = 1;
yearschedule.EndMonth = 1;
yearschedule.BeginDay = 1;
yearschedule.EndDay = 1;
yearschedule.BeginHour = 1;
yearschedule.EndHour = 1;
yearschedule.BeginMinute = 5;
yearschedule.EndMinute = 5;
yearschedule.BeginSecond = 0;
yearschedule.EndSecond = 5;
Monthly:
SPMonthlySchedule monthschedule = new SPMonthlySchedule();
monthschedule.BeginDay = 1;
monthschedule.EndDay = 1;
monthschedule.BeginHour = 1;
monthschedule.EndHour = 1;
monthschedule.BeginMinute = 15;
monthschedule.EndMinute = 30;
Weekly:
SPWeeklySchedule schedule = new SPWeeklySchedule();
schedule.BeginDayOfWeek = DayOfWeek.Monday;
schedule.BeginHour = 2;
schedule.BeginMinute = 1;
schedule.BeginSecond = 0;
schedule.EndSecond = 5;
schedule.EndMinute = 1;
schedule.EndHour = 2;
schedule.EndDayOfWeek = DayOfWeek.Monday;
Daily:
SPDailySchedule daySchedule = new SPDailySchedule();
daySchedule.BeginHour = 9;
daySchedule.BeginMinute = 0;
daySchedule.BeginSecond = 0;
daySchedule.EndSecond = 0;
daySchedule.EndMinute = 0;
daySchedule.EndHour = 9;
Hourly:
SPHourlySchedule hourSchedule = new SPHourlySchedule();
hourSchedule.BeginMinute = 10;
hourSchedule.EndMinute = 20;
Admin SVC must be running in order to create deployment timer job error in SharePoint
Now, we will discuss how to fix the error “Admin SVC must be running in order to create deployment timer job error” which comes while deploying a wsp in SharePoint.
When I added wsp solution for SharePoint 2010 with PowerShell and after this, I wanted to install it.
But when I installed a solution then I got an error. “Install-SPSolution: Admin SVC must be running in order to create deployment timer job”
So I found the solution for this.
Follow these step for resolving this error:
Go to “Control Panel -> Administrative Tools -> Services”, select SharePoint 2010 Administration and start it. Check the fig below:
After this you able to add the solution in your SharePoint successfully.
Failed to load receiver assembly timerjobprocess version for feature System.IO.FileNotFoundException:Could not load file or assembly or one o its dependencies. The system cannot find the file specifies
Now, we will discuss how to fix an error that comes while activating the feature in central administration in SharePoint 2016. I have created a timer job and then while activating the timer job from the central administration the below error is coming.
Sorry, something went wrong.
Failed to load receiver assembly “TimerJobProcess, Version=1.0.0.0. Culture=neutral, PublicKeyToken=1791eb” for feature “”TimerJobProcess_CustomTimerJobfeature: (ID: efc1ba2e-f6b7): System.IO.FileNotFoundException: Could not load file or assembly ‘TimerJobProcess, Version:1.0.0.0. Culture=neutral, PublicKeyToken={}’ or one of its dependencies. The System cannot find the file specified.
To fix the error follow the below steps:
Do an IISRESET.
If the issue does not get resolved then restart the timer job services. For this follow the below steps:
Go to Window+R -> services.msc.
Then click on “SharePoint Timer Service” and then click on Restart the service like below:
Error occurred in deployment step add solution a timerjobprocess feature with ID FeatureID has already been installed in this farm. Use the force attribute to explicitly re-install the feature in SharePoint 2016 timer job
This SharePoint tutorial explains, how to resolve the issue An error occurred in deployment step ‘add solution’ a timer job process feature with ID FeatureID has already been installed in this farm, that comes when we deploy a timer job in SharePoint 2016 on-premise environment.
While we were developing a custom timer job we faced the issue. The error comes as:
An error occurred in deployment step ‘add solution’ a timer job process feature with ID FeatureID has already been installed in this farm. Use the force attribute to explicitly re-install the feature. It looks like below:
An error occurred in the deployment step add solution a timer job process feature with ID FeatureID.
Open the solution in visual studio 2015/2017, open the feature, and then press F4 which will open the Properties windows. In the Properties windows, by default, Always Force Install will be False. Make that to true. So the property should look like below:
After this when you will deploy from visual studio 2015, the error will not come.
You may like the following tutorials:
- SharePoint get current user id, name, email, display name programmatically
- http error 503. the service is unavailable in SharePoint
- SharePoint Rest API Select, Filter, Sort and Paging Example
- Create remote event receiver SharePoint Online
I hope this SharePoint tutorial explains what is SharePoint timer jobs? How to create a SharePoint timer job using visual studio? Also, we saw how to create, debug and deploy SharePoint timer using visual studio.
After working for more than 15 years in Microsoft technologies like SharePoint, Office 365, and Power Platform (Power Apps, Power Automate, and Power BI), I thought will share my SharePoint expertise knowledge with the world. Our audiences are from the United States, Canada, the United Kingdom, Australia, New Zealand, etc. For my expertise knowledge and SharePoint tutorials, Microsoft has been awarded a Microsoft SharePoint MVP (9 times). I have also worked in companies like HP, TCS, KPIT, etc.