65.9K
CodeProject 正在变化。 阅读更多。
Home

在 SharePoint 中以编程方式创建和部署自定义计时器作业定义

starIconstarIconstarIconstarIconstarIcon

5.00/5 (25投票s)

2013年8月8日

CPOL

5分钟阅读

viewsIcon

242405

在 SharePoint 中以编程方式创建和部署自定义计时器作业定义。

什么是计时器作业???

计时器作业是 SharePoint 运行的后台进程。在中央管理中,从主页中选择“监视”链接,然后选择“计时器作业”部分下的“查看作业定义”链接,然后您将看到计划的计时器作业定义的列表。 

如何创建自定义计时器作业??

问题

每 15 分钟在 SharePoint 中执行一次代码,并将新记录添加到“任务”列表。

解决方案

需要创建计时器作业,使其每 15 分钟自动运行一次。以下是创建自定义计时器作业定义并部署它的步骤。

创建作业定义类

步骤 1

从 Visual Studio 2010 或 2012 中创建一个空的 SharePoint 项目,并命名为 TimerJobApplication。您可以为该项目取任何名称,但在我们的示例中,我们使用此名称。按“确定”并选择“部署为场解决方案”。

第二步

向项目中添加一个新类,并命名为 CustomTimerJob.cs。您可以为该类取任何名称,但在我们的示例中,我使用的是这个名称。

为此,请在解决方案资源管理器中右键单击项目名称,选择“添加”->“新项”。在“C#”类别下,选择“代码”选项卡,选择“类”并命名该类。

TimerJobApplication -> 添加 -> 新项 -> 类

步骤 3

将此 CustomTimerJob 类派生自 SPJobDefinition 类。

您需要添加以下语句来实现此目的。

using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;

public class CustomTimerJob : SPJobDefinition
    {}

步骤 4

为您的类添加以下 3 个构造函数。

public CustomTimerJob() : base() { }

public CustomTimerJob(string jobName, SPService service): 
          base(jobName, service, null, SPJobLockType.None)
{
    this.Title = "Task Complete Timer";
}

public CustomTimerJob(string jobName, SPWebApplication webapp): 
        base(jobName, webapp, null, SPJobLockType.ContentDatabase)
{
    this.Title = "Task Complete Timer";
}

步骤 5

重写 Execute() 方法来执行您的操作。每当计时器作业执行时,它将运行 Execute() 方法中编写的代码。

public override void Execute(Guid targetInstanceId)
{
    SPWebApplication webApp = this.Parent as SPWebApplication;
        SPList taskList = webApp.Sites[0].RootWeb.Lists["Tasks"];
        SPListItem newTask = taskList.Items.Add();
        newTask["Title"] = "New Task" + DateTime.Now.ToString();
        newTask.Update();
}

在我们的示例中,每当计时器作业执行时,都会向 Tasks 列表添加一条新记录。您可以在此处编写自己的逻辑。

以下是 CustomTimerJob 类的完整代码文件。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Administration;
using System.Data;
using System.IO;
namespace TimerJobApplication
{
    public class CustomTimerJob : SPJobDefinition
    {
        public CustomTimerJob() : base() { }
        public CustomTimerJob(string jobName, SPService service)
                    : base(jobName, service, null, SPJobLockType.None)
            {
            this.Title = "Task Complete Timer";
            }
               public CustomTimerJob(string jobName, SPWebApplication webapp)
            : base(jobName, webapp, null, SPJobLockType.ContentDatabase)
        {
            this.Title = "Task Complete Timer";
        }
            public override void Execute(Guid targetInstanceId)
        {
            SPWebApplication webApp = this.Parent as SPWebApplication;
            SPList taskList = webApp.Sites[0].RootWeb.Lists["Tasks"];
            SPListItem newTask = taskList.Items.Add();
            newTask["Title"] = "New Task" + DateTime.Now.ToString();
            newTask.Update();
        }
    }
}

注册计时器作业定义

步骤 6

添加一个新功能来注册我们的自定义计时器作业。

为此,请在解决方案资源管理器中右键单击项目内的“功能”并单击“添加功能”。

将此功能重命名为 CustomTimerJobFeature。

将此功能的范围设置为“Web 应用程序”。

为此,请双击 CustomTimerJobFeature 并选择范围“Web 应用程序”。现在按 F4,它将打开功能的属性窗口。在“默认激活”中选择

选择“否”的原因是,我们需要为功能指定 Web 应用程序级别的范围,并且我们不希望将其激活到所有应用程序。您需要为要注册计时器作业的应用程序激活此功能。

步骤 7

为此功能添加功能事件接收器。

右键单击 CustomTimerJobFeature 并选择“添加事件接收器”。

将以下代码写入 CustomTimerJobFeatureEventReceiver.cs 类。

using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Security;
using Microsoft.SharePoint.Administration;
namespace TimerJobApplication.Features.CustomTimerJobFeature
{
[Guid("e6ea0027-1187-419d-b357-306244d0ae37")]
    public class CustomTimerJobFeatureEventReceiver : SPFeatureReceiverimer
    {
        const string JobName = "New Task Timer";
        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
            {
                CustomTimerJob job = new CustomTimerJob(JobName, site);
                SPMinuteSchedule schedule = new SPMinuteSchedule();
                schedule.BeginSecond = 0;
                schedule.EndSecond = 59;
                schedule.Interval = 15;
                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;
        }
        public override void FeatureDeactivating(SPFeatureReceiverProperties properties)
        {
 
            lock (this)
            {
                try
                {
                    SPSecurity.RunWithElevatedPrivileges(delegate()
                    {
                        SPWebApplication parentWebApp = (SPWebApplication)properties.Feature.Parent;
                        DeleteExistingTimerJobFromSite(this.JobName, parentWebApp);
                    });
                }
                catch (Exception ex)
                {
                    throw ex;
                }
            }
        }
    }
}

您可以根据需要创建不同的计划。在这里,我们创建了 SPMinuteSchedule 来每 15 分钟执行一次我们的作业。

您也可以根据需要使用其他计划。以下是计划列表。

类名 循环
SPYearlySchedule 每年运行一次计时器作业
SPMonthlySchedule 每月在指定日期运行一次计时器作业。
例如,每月的 15 日
SPMonthlyByDaySchedule 每月在指定的日期和星期运行一次计时器作业。
例如,每月的第三个星期五
SPWeeklySchedule每周运行一次计时器作业
SPDailySchdedule 每天运行一次计时器作业
SPHourlySchedule 每小时运行一次计时器作业
SPMinuteSchedule 每 n 分钟运行一次计时器作业
其中 nInterval 属性中的值
SPOneTimeSchedule 运行一次计时器作业

部署和调试

在解决方案资源管理器中右键单击项目名称并选择“部署”。

成功部署后,您需要手动激活该功能,因为我们将“默认激活”属性设置为

打开中央管理并选择“管理 Web 应用程序”。

选择您的 Web 应用程序,然后在功能区控件中选择“管理功能”选项卡,此时会弹出一个窗口显示您应用程序范围内的所有功能。找到我们在此创建的功能并激活它。

激活功能后,您的计时器作业将被注册。要查看所有已注册计时器作业的列表,请转到中央管理并选择“监视”部分。

选择“查看作业定义”。

您将能够看到所有已注册的计时器作业。在此列表中,您还会找到我们自定义的计时器作业。

您在 Execute() 方法中编写的代码将开始每 15 分钟(或您设置的任何计划)执行一次。

调试计时器作业

调试计时器作业与调试普通 C# 代码相当不同。您需要附加“OWSTIMER.EXE”。

为此,在部署项目后,每当您想调试 Execute() 方法时,请按 CTRL+ALT+P 并选择“OWSTIMER.EXE”进程,然后单击“附加”。您也可以从“调试”菜单手动打开此对话框。

调试 -> 附加到进程

现在,在 Execute() 方法处设置断点,这样每当您的计时器作业执行时,您就可以调试代码。

如果您不想等待计时器作业执行(在我们的例子中是 15 分钟),为了测试目的,您可以直接从中央管理运行计时器作业。为此,请选择“所有作业定义”中列出的计时器作业,它将为您提供“运行”或“禁用”作业的选项,您也可以设置时间计划。

重要提示

请注意,每当您更改 Execute() 方法中的逻辑或代码时,都必须从 Services.msc 重新启动计时器服务。如果您仅部署而不重新启动服务,它将不会采用您的最新更新。因此,请始终养成从 Services.msc 重新启动“SharePoint Timer Service”的习惯。

如果您在注册或部署计时器作业时仍然遇到任何问题,请尝试卸载程序集并重启 IIS,然后再次部署。

要卸载程序集,请在“运行”中键入“assembly”并按 Enter。在程序集列表中,您将看到您项目名称的程序集。选择它并通过右键单击进行卸载。

要重启 IIS,请在“运行”中键入 iisreset 并按 Enter。

© . All rights reserved.