Andrew Connell [MVP SharePoint]
1728 Posts |  46 Articles |  5281 Comments
.NET  |  MCMS  |  SharePoint  |  Office System
AC's Blog Quick Links
SharePoint Quick Links
Article Categories
Archives
February, 2012 (2)
January, 2012 (12)
December, 2011 (6)
November, 2011 (3)
October, 2011 (17)
September, 2011 (8)
August, 2011 (6)
July, 2011 (7)
June, 2011 (13)
May, 2011 (9)
April, 2011 (15)
March, 2011 (1)
February, 2011 (6)
January, 2011 (5)
December, 2010 (11)
November, 2010 (6)
October, 2010 (12)
September, 2010 (5)
August, 2010 (4)
July, 2010 (5)
June, 2010 (6)
May, 2010 (11)
April, 2010 (11)
March, 2010 (9)
February, 2010 (9)
January, 2010 (3)
December, 2009 (10)
November, 2009 (15)
October, 2009 (15)
September, 2009 (7)
August, 2009 (4)
July, 2009 (10)
June, 2009 (8)
May, 2009 (2)
April, 2009 (9)
March, 2009 (6)
February, 2009 (16)
January, 2009 (6)
December, 2008 (12)
November, 2008 (12)
October, 2008 (27)
September, 2008 (13)
August, 2008 (14)
July, 2008 (14)
June, 2008 (12)
May, 2008 (23)
April, 2008 (12)
March, 2008 (15)
February, 2008 (13)
January, 2008 (12)
December, 2007 (10)
November, 2007 (8)
October, 2007 (15)
September, 2007 (20)
August, 2007 (21)
July, 2007 (16)
June, 2007 (8)
May, 2007 (25)
April, 2007 (16)
March, 2007 (18)
February, 2007 (18)
January, 2007 (12)
December, 2006 (16)
November, 2006 (13)
October, 2006 (18)
September, 2006 (22)
August, 2006 (27)
July, 2006 (23)
June, 2006 (23)
May, 2006 (23)
April, 2006 (9)
March, 2006 (17)
February, 2006 (15)
January, 2006 (23)
December, 2005 (31)
November, 2005 (32)
October, 2005 (38)
September, 2005 (53)
August, 2005 (30)
July, 2005 (63)
June, 2005 (30)
May, 2005 (59)
April, 2005 (29)
March, 2005 (74)
February, 2005 (27)
January, 2005 (22)
December, 2004 (32)
November, 2004 (42)
October, 2004 (39)
September, 2004 (20)
August, 2004 (14)
July, 2004 (27)
June, 2004 (40)
May, 2004 (5)
April, 2004 (6)
March, 2004 (16)
February, 2004 (26)
January, 2004 (23)
December, 2003 (7)
November, 2003 (14)
October, 2003 (20)
September, 2003 (4)
Post Categories
Add to Technorati Favorites

Managed Windows Shared Hosting

In previous versions of SharePoint (or other platforms), if you had some task you wanted to perform on a scheduled basis, you'd have to either create a console EXE and schedule it to run via Windows Task Scheduler (ala AT.EXE) or create a Windows Service that went to sleep for a period of time. In order to install (and maintain) these tasks, you had to have console access to your production SharePoint (or other app) servers... something IT or admins wouldn't easily hand out.

Addressing this issue, Microsoft has added something called timer jobs to Microsoft Office SharePoint Server (MOSS) 2007. Microsoft uses timer jobs to do things like dead web cleanup (purging unused sites from site collections) among others. To see what other timer jobs are out there, from Central Administration, click Operations and then Timer Job Definitions. Not only does Microsoft use timer jobs in MOSS, but you can create your own custom timer jobs to do your own scheduled tasks. What's nice about this is once your timer job has been installed (something you can easily do with a solution & a feature), you can view it's status through Central Administration and even disable/enable it... all without console access to your production servers! Another cool thing is that when your job runs, MOSS passes it the GUID of the content database for the site the job is registered with. You can use this GUID to obtain a reference to a content database, then a site collection, and finally a site within the collection (SPWeb).

How do you build one? Well, unfortunately the documentation is lacking here... there isn't a single article in the SDK talking about creating custom timer jobs and the necessary objects aren't well documented either.

Everything surrounds the Microsoft.SharePoint.Administration.SPJobDefinition object. Create a new class that inherits from SPJobDefinition, implement a few constructors and a single method: Execute(Guid). I created a simple timer job that (assuming it's associated with a WSS site created using the Team Site template and there's a Tasks list in the root of the site) creates a new task every 5 minutes when the job is enabled. Here's what the constructors look like ([update 1/11 12p] added a default empty constructor[/]): 

   1:  public TaskLoggerJob ()
   2:      : base(){
   3:  }
   4:  public TaskLoggerJob (string jobName, SPService service, SPServer server, SPJobLockType targetType)
   5:      : base(jobName, service, server, targetType) {
   6:  }
   7:  public TaskLoggerJob (string jobName, SPWebApplication webApplication)
   8:      : base(jobName, webApplication, null, SPJobLockType.ContentDatabase) {
   9:    this.Title = "Task Logger";
  10:  }

Now, after you build the assembly containing your custom timer job and add it to the GAC (a requirement), you need to associate it with a specific site, site collection, web application, or farm and specify a schedule for when it should run. Ideally I'd like to do this with STSADM.EXE, but no such command exists (custom command opportunity out there!). Another way is to do this through the object model. Because I want to minimize any console access requirements, I'll do this in a feature by implementing the FeatureActivated event. To do this, you create an instance of your job, set the schedule, and call update like so: 

   1:  // get a reference to our job in the GAC
   2:  TaskLoggerJob taskLoggerJob = new TaskLoggerJob("Task Logger", site.WebApplication);
   3:  // set the execution schedule 
   4:  SPMinuteSchedule schedule = new SPMinuteSchedule();
   5:  schedule.BeginSecond = 0;
   6:  schedule.EndSecond = 59;
   7:  schedule.Interval = 5;
   8:  taskLoggerJob.Schedule = schedule;
   9:  //update the job
  10:  taskLoggerJob.Update();

That's it! Course you should take this a step further by packaging all this up in a solution that will deploy the assembly to the GAC and install a feature. Then, upon activating the feature, it will associate the web with the timer job. Conversely, upon deactivating the feature, it removes the timer job. Very slick! 

» MOSS SDK: Microsoft.SharePoint.Administration.SPJobDefinition

[Update 2/1/2007 @ 10p] Due to the great number of comments and questions triggered by this post, I took the time to write a new article explaining in more detail, with sample code, how to create a custom timer job. Please review that article before asking any questions: Creating custom SharePoint Timer Jobs. I'm closing the comments on this post... please post all new comments ot the article linked here.

[Update 7/2/2007 @ 11p] Make sure you don't use visible Features when deploying your custom timer jobs as explained here in this post.

[Update 4/8/2008 @ 12a] A Visual How-To I created on the subject of creating custom timer jobs was recently posted on MSDN. You can get more info here.

[Update 5/1/2008 @ 730a] There is now an in-depth article on MSDN about creating custom timer jobs. If you have trouble please check this out as there is a ton of additional info here. Post: More Help on Creating Custom Timer Jobs

Technorati tags: , ,
posted on Wednesday, January 10, 2007 10:25 PM

Feedback

# re: MOSS Timer Jobs - Create Your Own! 1/29/2007 7:29 AM Vijay
Gravatar Thanks for the article, appreciate if you could also provide a zip sample that we can built and work on.

# re: MOSS Timer Jobs - Create Your Own! 1/30/2007 2:59 AM suja
Gravatar Hi
I was able to create my timer job and i can see it getting scehduled properly. As per my understanding it should call the Execute () everytime it gets initiated. But this doesnt seem to happen with my job. Is my understanding correct? If not where should I put my custom job definition so that everytime it gets executed.
Plz help out.
Thanks
Suja

# re: MOSS Timer Jobs - Create Your Own! 1/30/2007 4:26 AM szach
Gravatar Hi

I would like to know more about the Execute () you ve mentioned. Do we need t ooverride this method??

# re: MOSS Timer Jobs - Create Your Own! 1/30/2007 10:29 PM AC [MVP MCMS]
Gravatar Suja - Yes, the Execute method should get executed. The assemly containing it should depoyed to the the GAC.

# re: MOSS Timer Jobs - Create Your Own! 1/30/2007 10:29 PM AC [MVP MCMS]
Gravatar Szach - Yes

# re: MOSS Timer Jobs - Create Your Own! 1/30/2007 11:49 PM suja
Gravatar Andrew,
I do have my SPJobDefinition class with the constructors you have given plus the Execute () which keeps adding a new list item to my custom list.(just to test...)
I 've deployed it to the GAC.
I used an exe to create an object of the timer class and scheduled it.
I can see my timer job getting scheduled properly and running under the list of timer jobs in Central Administration.
But i donno what it is doing once it has strated.
The custom code in Execute() is not being called....:(

wht can be the reason....plz help me out

Thanks
suja


# re: MOSS Timer Jobs - Create Your Own! 1/31/2007 1:19 AM suja
Gravatar Andrew

My list is now flooded with new items created by Timer job...:)
:) :)

Thanks for your reply and for the "gr8 post" which was really IN TIME for me.

I read your blog once again determined to find the wht is missing in my code..;)I assumed that your task creation actually happened in the Execute().Also, this Execute() is called in one of the constructors.
Thts it....:)

Thnks again
Suja


# re: MOSS Timer Jobs - Create Your Own! 1/31/2007 10:02 AM Swati
Gravatar hi

I would like to know if the code above is used to change the Job title 5 minutes after the feature is activated?

Thanks

# re: MOSS Timer Jobs - Create Your Own! 1/31/2007 10:16 AM AC [MVP MCMS]
Gravatar Suja - Good to see you got it working. Execute() is not called by the constructors. You're overloading the method (hence inheriting from SPJobDefinition) and SharePoint is calling that method.

Swati - The code above is used to create a new job and assign a schedule to it. To change the schedule, you get a reference to the job and simply change the Schedule property.

# re: MOSS Timer Jobs - Create Your Own! 2/1/2007 2:28 AM suja
Gravatar Andrew

I meant

public Class1(string jobName, SPWebApplication webApplication)
: base(jobName, webApplication, null, SPJobLockType.ContentDatabase)
{

this.Title = "Custom Job";
this.Execute(Id);

}

This made my timer job work.
Thnx
suja

# re: MOSS Timer Jobs - Create Your Own! 2/1/2007 5:58 AM Ankush Bhatia
Gravatar hi
1)the task is geeting scheduled in the Timer Job Defination in Central admin ,but we are not able to see the schdule in the Timer job status , can u please tell where can we see the schedule of the job .
2)correct me if i am wrong Should the task we want to perform be placed in the exceute method right??
pls comment!!


# re: MOSS Timer Jobs - Create Your Own! 2/1/2007 9:26 AM AC [MVP MCMS]
Gravatar Suja - that is most certainly NOT the way you should be doing it. SharePoint will call your Execute method, just give it time for your schedule to kick in. What you've done is now everytime your object is creaeted, it will fire off the execution, which is not what you want (when you uninstall, it will always execute it again).

Ankush - Make sure you have set the schedule correctly. The status won't appear until the job runs the first time. And yes, the task you want to perform should be added to the Execute() method.

# re: MOSS Timer Jobs - Create Your Own! 2/1/2007 11:50 AM Srinivas
Gravatar Hi Andrew,

I have an SPService running. The problem is when it is diplayed in the "Services on Server" page the fully qualified class name (including namespace) of the service is displayed. Is there a way that i can display a user friendly name instead of the fully qualified class name. I could see some properties like "DisplayName", "TypeName" properties defined on the SPService but these are only Get properties. Please let me know if you could help me in this regard.

Thanks,
Srinivas.

# re: MOSS Timer Jobs - Create Your Own! 2/1/2007 11:15 PM AC [MVP MCMS]
Gravatar ALL - I'm closing comments on this post. Please see the original post for an updated message on February 1st that points to a new article with more information about creating custom timer jobs (including sample code).

# re: MOSS Timer Jobs - Create Your Own! 1/11/2007 7:25 AM Andy
Gravatar Thank you! I've been trying to find out how to use the SharePoint jobs, and hit this complete lack of documentation. I ended up having to build a Windows service. Oh well, this can be a feature for the next version.

Any chance of zip file of your demo code? Just I'm still not quite clear about how you associated your job with a site/app/farm...

# re: MOSS Timer Jobs - Create Your Own! 1/11/2007 9:51 AM AC [MVP MCMS]
Gravatar Andy - Look at the second code snippet in the post... Add that code to the feature even receiver FeatureActivated. The only thing that should be above that line is obtaining a reference to the site itself, which you can get from the SPFeatureReceiverProperties that are passed in as the sole parameter for FeatureActivated:

SPSite site = properties.Feature.Patent as SPSite;

You'll see in the snippet I get an instance of the TaskLoggerJob and pass in the WebApplication I want to add the job to, then set the schedule, and call Update to commit my changes.

# re: MOSS Timer Jobs - Create Your Own! 1/11/2007 12:36 PM Eric
Gravatar I am getting an error:

... cannot be deserialized because it does not have a public default constructor.


Any idea what I'm missing?

# re: MOSS Timer Jobs - Create Your Own! 1/11/2007 1:00 PM AC [MVP MCMS]
Gravatar Eric - Yeah... looks like I forgot to add my default constructor... I revised the code in the post to include a constructor with no parameters.

# re: MOSS Timer Jobs - Create Your Own! 1/11/2007 1:03 PM Eric
Gravatar Thanks. I added my default constructor already and was still receiving the same error. Maybe it wasn't being updated.

# re: MOSS Timer Jobs - Create Your Own! 1/11/2007 3:08 PM AC [MVP MCMS]
Gravatar Eric - Make sure you're re-GAC'ing your assembly after making the change with the force switch. If you're unsure, remove it from the GAC and reinstall it to the GAC after making the change.

# re: MOSS Timer Jobs - Create Your Own! 1/12/2007 2:50 AM SSA
Gravatar Excellent post!

Thanks

SSA
http://sharepointblogs.com/ssa

# re: MOSS Timer Jobs - Create Your Own! 1/13/2007 2:50 PM Todd Bleeker
Gravatar I looked into this about a year ago but I didn't see how to tap this functionality. I was even told that the Timer was only available to Microsoft DLLs.

Glad you figured this out; I'm sure that we will put it to good use.

<Todd />

# Links (1/11/2007) 1/14/2007 7:44 AM Member Blogs
Gravatar .NET, C#, VB.NET **** Enumerated type arrays in .NET vs. Delphi - not available in CF though because

# re: MOSS Timer Jobs - Create Your Own! 1/16/2007 2:57 AM Ankush
Gravatar I still cannot figure out how is the job created?????

# re: MOSS Timer Jobs - Create Your Own! 1/16/2007 9:31 AM AC [MVP MCMS]
Gravatar Ankush - As stated in the post, you simply create a feature receiver and override the FeatureActivated event. Then, paste the second code sample in my post into that event handler and you're good to go. If you're having trouble, how about asking a more precise question instead of a random question.

# re: MOSS Timer Jobs - Create Your Own! 1/16/2007 10:41 AM Gunnar Hafsteinsson
Gravatar Hi, I am implementing a SharePoint web using WSS3.0 and I need to implement a schedule job for a certain functionality. The sample code that you supply would be perfect for my implementation but I am not using MOSS, is this a MOSS only feature or can you also do this in WSS3.0?

# re: MOSS Timer Jobs - Create Your Own! 1/16/2007 12:19 PM AC [MVP MCMS]
Gravatar Gunnar - I don't have a WSS only installation handy, but because the SPJobDefinition class is in the WSS v3 SDK, I'd assume you can use timer jobs in WSS as well.

# re: MOSS Timer Jobs - Create Your Own! 1/17/2007 11:57 PM S
Gravatar hi
I am new to xml
I am not able to craete the xml file for the elment manifest tag.Could you help me out
Thanks in advance

# re: MOSS Timer Jobs - Create Your Own! 1/18/2007 5:39 AM James Orton
Gravatar Hi Andrew,

Great site, this information is so hard to find. I've created the job and install it.

How do use the content db GUID to reference my site collection?

Is it possible to attach the VS project to a process so I can run the code in the debugger? If I cannot use the debugger, do you know if there's a way I can write to the event log or the sharepoint log files so I can determine which lines of code in my execute routine are failing?

Regards,
James


# re: MOSS Timer Jobs - Create Your Own! 1/19/2007 8:57 AM AC [MVP MCMS]
Gravatar S - First thing you need to do is dig into the WSS v3 SDK in the section on Features & Solutions. You'll see plenty of samples for the feature.xml and element manifest files: http://msdn2.microsoft.com/en-us/library/ms439657.aspx

# re: MOSS Timer Jobs - Create Your Own! 1/19/2007 8:59 AM AC [MVP MCMS]
Gravatar James - For the using the GUID to get a reference to your site collection, here's a snippet to get you going:
SPWebApplication webApplication = this.Parent as SPWebApplication;
SPContentDatabase contentDb = webApplication.ContentDatabases[contentDbId];
SPSite siteCollection = contentDb.Sites[0];

As for debugging your timer job, you want to manually attach the VS debugger to the OWSTIMER.EXE process... that's the Windows Service that is actually kicking off the timer jobs.

# re: MOSS Timer Jobs - Create Your Own! 1/20/2007 3:25 AM s
Gravatar hey hi
just want to know if the windows sharepoint service timer should be activated for this job scheduling to work

# re: MOSS Timer Jobs - Create Your Own! 1/20/2007 10:28 AM AC [MVP MCMS]
Gravatar If you're asking "should the WSS Timer Service should be started in Administration Tools -> Services", then the answer is yes. That's the Windows Service that runs all installed timer jobs.

# re: MOSS Timer Jobs - Create Your Own! 1/22/2007 6:06 AM skb
Gravatar hi
the Administration Tools -> Services is started
what i meant was the windows sharepoint service timer, whose status can be viewed in-
Central Administration>Operations>Topology and Services>Services on Server

bcoz in my case it neither shows it as started nor stopped
Could this be the reason why my scheduler is not working

One more thing could this be the reason why the "Enable Expiry" in information policy setting is not working

# re: MOSS Timer Jobs - Create Your Own! 1/22/2007 2:37 PM jeff
Gravatar Great information (And the only info I can find on the web) on jobs.

I found another way to add this job:

SPSite spsite = new SPSite("http://contentvm1/");
ConnectorJob job = new ConnectorJob(name, spsite.WebApplication);
...

The job was added, and I can see it was executed as scheduled. However, the logging code in my job's execute() method doesn't produce any logs. Strange.

Jeff

# re: MOSS Timer Jobs - Create Your Own! 1/24/2007 11:51 PM soumya
Gravatar This site provides a very useful info..
Please let me know how to implement execute method?

# re: MOSS Timer Jobs - Create Your Own! 1/25/2007 2:19 PM Todd T
Gravatar I have a requirement to modify files on each server in the farm at install/uninstall time. My current approach is to create a timer job for the Farm.TimerService so that the job will get created on each server in the farm. This job is created through a feature receiver's events for install and uninstall and that feature is added via a solution. This seems to be working pretty good for the install time case.

However, for the uninstall case it doesn't work because the timer job is created and scheduled (as a one-time job with DateTime.Now) during the solution retract, but the job is not necessarily executed before the solution retract is complete and therefore the dll removed from the GAC.

So my question is, is there a way to create and schedule a one-time immediate job and then wait for the job to be executed before allowing the feature receiver event to return and thus causing the deploy/retraction of the solution to wait as well?

I essentially need to make the timer job execution a part of the solution deployment/retraction itself, rather than getting executed after the fact.

I can't think of any way to get access to each server in the farm in order to make these necessary file changes at install/uninstall time. That is, without requiring an install/uninstall on each server, which is not an option.

Any suggestions would be greatly appreciated.

# re: MOSS Timer Jobs - Create Your Own! 1/25/2007 2:47 PM AC [MVP MCMS]
Gravatar Soumya - Huh? Its just adding your own logic that's implementing the Execute method. If you're looking for help on how to use the provided GUID to obtain a reference to a site collection or web, check this reply to another comment: http://www.andrewconnell.com/blog/archive/2007/01/10/5704.aspx#5811

# re: MOSS Timer Jobs - Create Your Own! 1/25/2007 2:50 PM AC [MVP MCMS]
Gravatar ToddT - Unfortunately we have no events we can trap when deploying/retracting solutions... only install/uninstall & activate/deactivate with features. The only thing I can think of is for your job to write some value somewhere once it's run, and your uninstaller should check if that value exists. If so, you can remove it... otherwise, leave it. Unfortunately though, it will still remove the DLL from the GAC.

Comments have been closed on this topic.

Copyright © 2003 - 2012 Andrew Connell
Creative Commons License 
This work is licensed under a Creative Commons License
Site design by Heather Solomon.

 
 
SharePoint 2010 Training
Looking for SharePoint 2010 training for developers, administrators, SharePoint Designer 2010 and end users? Look no further! My company, Critical Path Training offers the best SharePoint training around!