Мои предложения:
- не создавайте консольное приложение, создайте класс, который наследуется от
SPJobDefinition
.
- установите
SPJobLockType.Job
на этот таймер, это даст гарантию, что задание будет выполнено только один раз во всей ферме, даже если вы используете несколько внешних серверов
- в задании таймера откройте нужные вам объекты
SPSite
, SPWeb
и найдите SPList
\
- Использование
SPQuery
отфильтровывает только те элементы, которые вам нужны - я полагаю, вам придется отфильтровать те, где Status! = Complete
- Цикл по сбору результатов (который будет иметь тип
SPListItemCollection
, примените ваши правила, отметьте DueDate
и Datetime.Now
, отправьте электронные письма
- Поскольку задача - это просто
SPListItem
, у нее есть свойство Properties
, которое на самом деле представляет собой пакет свойств - вы можете добавлять любые свойства, которые вам нужны. Итак, добавим свойство My_LastSentReminderDate
. Используйте это свойство, чтобы проверить, не отправляете ли вы слишком много «корпоративного спама»: -)
- Чтобы установить
SPJobDefinition
в ферме SharePoint, вы можете использовать скрипт PowerShell. При необходимости могу привести примеры.
Не забудьте Threading.Thread.CurrentThread.CurrentCulture = Your_SPWeb_Instance.Locale
, иначе сравнение дат может не сработать, если в Интернете есть другой языковой стандарт!
РЕДАКТИРОВАТЬ: Вот как типичное напоминание выглядит в моих приложениях:
Public Class TypicalTimer
Inherits SPJobDefinition
Public Sub New(ByVal spJobName As String, ByVal opApplication As SPWebApplication)
'this way we can explicitly specify we need to lock the JOB
MyBase.New(spJobName, opApplication, Nothing, SPJobLockType.Job)
End Sub
Public Overrides Sub Execute(ByVal opGuid As System.Guid)
'whatever functionality is there in the base class...
MyBase.Execute(Guid.Empty)
Try
Using oSite As SPSite = New SPSite("http://yourserver/sites/yoursite/subsite")
Using oWeb As SPWeb = oSite.OpenWeb()
Threading.Thread.CurrentThread.CurrentCulture = oWeb.Locale
'find the task list and read the "suspects"
Dim oTasks As SPList = oWeb.Lists("YourTaskListTitle")
Dim oQuery As New SPQuery()
oQuery.Query = "<Where><Neq><FieldRef Name='Status'/>" & _
"<Value Type='Choice'>Complete</Value></Neq></Where>"
Dim oUndoneTasks As SPListItemCollection = oTasks.GetItems(oQuery)
'extra filtering of the suspects.
'this can also be done in the query, but I don't know your rules
For Each oUndoneTask As SPListItem In oUndoneTasks
If oUndoneTask(SPBuiltInFieldId.TaskDueDate) IsNot Nothing AndAlso _
CDate(oUndoneTask(SPBuiltInFieldId.TaskDueDate)) < Now().Date Then
' this is where you send the mail
End If
Next
End Using
End Using
Catch ex As Exception
MyErrorHelper.LogMessage(ex)
End Try
End Sub
End Class
Чтобы зарегистрировать задание таймера, я обычно использую такой сценарий:
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint")
[System.Reflection.Assembly]::LoadWithPartialName("Microsoft.SharePoint.Administration")
[System.Reflection.Assembly]::LoadWithPartialName("Your.Assembly.Name.Here")
$spsite= [Microsoft.SharePoint.SPSite]("http://yourserver/sites/yoursite/subsite")
$params = [System.String]("This text shows up in your timer job list (in Central Admin)", $spsite.WebApplication
$newTaskLoggerJob = new-object -type Your.Namespace.TypicalTimer -argumentList $params
$schedule = new-object Microsoft.SharePoint.SPDailySchedule
$schedule.BeginHour = 8
$schedule.BeginMinute = 0
$schedule.BeginSecond = 0
$schedule.EndHour = 8
$schedule.EndMinute = 59
$schedule.EndSecond = 59
$newTaskLoggerJob.Schedule = $schedule
$newTaskLoggerJob.Update()