Wednesday, February 11, 2015

Custom Timer job in Sharepoint 2010 using Visual Studio

Sharepoint provided a platform to develop timer jobs and deploy in its environment. We can monitor the jobs in central admin along with other jobs. Scheduler configuration is also possible through central admin.

To manage timer jobs, acces to Central Administrator > Monitoring > Review Job definitions
And to monitor job executions, Central Administrator > Monitoring > Check Job Status


Let’s create a sample Timer job and deploy it for better understanding.

Requirement: We have project sites for each project where their health statuses etc. are maintained in predefined template lists.  Now, customers need a dashboard to look into the project status at one place along with individual sites’ links.

Approach: For this, we are creating a list with required details in parent site and we develop a Timer Job to which runs at certain interval and updates the statuses of all sites into this list and a dashboard is created using this list.

Step 1: Create ‘Project Statistics’ list in Site collection / Parent site and ‘Project Details’ in child site (Individual project sites)

Step 2: Now we need to create a Timer job. To do this, follow below steps
  1. Open Visual Studio and create a new project using  ‘Empty Sharepoint Project’ Template

  2. If Sharepoint has single Server, provide the web application where it has to be deployed and don’t forget to select ‘Deploy as a Farm Solution’ and then click on ‘Finish'

    Note: If site url is not provided, we can package it and deploy the WSP solution using Powershell.
  3. Now, create a new class file in visual studio and extend the class from ‘SPJobDefinition’. Use below code as sample reference
         public StatusUpdateTimerJob()  
           : base()  
         {  
         }  
         public StatusUpdateTimerJob(string jobName, SPService service,  
             SPServer server, SPJobLockType lockType)  
             : base(jobName, service, server, lockType)  
         {  
           this.Title = "Project Status Update Timer Job";  
         }  
         public StatusUpdateTimerJob(string jobName, SPWebApplication webapp)  
           : base(jobName, webapp, null, SPJobLockType.ContentDatabase)  
         {  
           this.Title = "Project Status Update Timer Job";  
         }  
         public override void Execute(Guid targetInstanceId)  
         {  
           //Write your logic to delete existing records from main list (Project Statistics) in parent site and then  
           //Iterate through all child sites and insert new records to above list from 'Project Details' list  
         }  
    
    Above code has 3 overloaded constructors which will be called internally as per need and write your logic in Execute method
  4. Now we create a feature to install and uninstall the Job. To do this, right click on ‘Features’ in solution explorer or Visual studio and click ‘Add Feature’

    Provide Feature Title and Description , this will be displayed in Features list of a site collection and select scope to ‘Site’


    In the event Receiver class of the above created feature, replace the code with below
     const string JobName = "ProjectStatus Update Timer Job";  
     public override void FeatureActivated(SPFeatureReceiverProperties properties)  
     {  
          SPSite site = properties.Feature.Parent as SPSite;  
          DeleteJob(site); // Delete Job if already Exists  
          CreateJob(site); // Create new Job  
     }  
     private static void DeleteJob(SPSite site)  
     {  
          foreach (SPJobDefinition job in site.WebApplication.JobDefinitions)  
               if (job.Name == JobName)  
                    job.Delete();  
     }  
     private static void CreateJob(SPSite site)  
     {  
          StatusUpdateTimerJob job = new StatusUpdateTimerJob(JobName, site.WebApplication);  
          SPMinuteSchedule schedule = new SPMinuteSchedule();  
          schedule.BeginSecond = 0;  
          schedule.EndSecond = 5;  
          schedule.Interval = 5;  
          job.Schedule = schedule;  
          job.Update();  
     }  
     public override void FeatureDeactivating(SPFeatureReceiverProperties properties)  
     {  
          DeleteJob(properties.Feature.Parent as SPSite); // Delete the Job  
     }  
    

    The above methods are to Create Job and Delete job which are called when feature activated and deactivated accordingly.
  5. Now are ready with our Timer job and we have to deploy it in the server. We can deploy it directly from Visual studio using ‘deploy’ Option in ‘debug ‘ or by packaging and installing the Solution
    To install Solution, use below Powershell commands
     Add-SPSolution -LiteralPath c:\SampleTImerjob.wsp  
     Install-SPSolution -Identity SampleTImerjob.wsp -GACDeployment  
     enable-spfeature -identity SampleTImerjob _Feature1 -url ‘Site collection URL’  
    
    We deployed it in GAC, as it’s a Timer job and should be accessed globally.

    Note: 1st 2 commands should be executed in one window and the last one should be in a new window as the dll is deployed in GAC, it will not reflect for the powershell window if we try to enable in same window
Step 3: Using above commands, we even activated the feature. So, the job will be created and it is scheduled. You can see it in ‘Central Admin’ as explained in the starting

We can also reconfigure the schedule by clicking on the title.


With this we implemented our requirement and for every 2 minutes, statuses for all project sites are updated in parent site and the dashboard is prepared on top of the list.

One important point to not to forget is, if we are modifying the Timer job, we have to update the Assembly version number. If not, the changes might not reflect properly

No comments:

Post a Comment