Dường như bạn cần một tính năng phạm vi trang trại, cài đặt dịch vụ chạy công việc này. Đây là cách tôi đã làm nó (sử dụng mã được viết bởi một đồng nghiệp, phải trung thực, nhưng anh ấy không ở trong SO).
Tạo tệp feature.xml với bộ thu sự kiện tính năng.
<Feature
Id="..."
Title="..."
Description="..."
Scope="Farm"
Version="1.0.0.0"
Hidden="FALSE"
ReceiverAssembly="XXX.FarmService, Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxx"
ReceiverClass="XXX.FarmService.XXXFarmFeatureEventReceiver"
xmlns="http://schemas.microsoft.com/sharepoint/">
</Feature>
Bên trong nhận sự kiện:
public override void OnFeatureActivated(SPFeatureReceiverProperties properties)
{
try
{
SPFarm farm = SPFarm.Local;
// Get Service, if it already exists
JobService myService = null; // JobService is a subclass of SPService
foreach (SPService service in farm.Services)
{
if (String.Compare(service.Name, JobService.XXXServiceName, true) == 0)
{
myService = (service as JobService);
break;
}
}
if (cegService == null)
{
// Create service
myService = new JobService(farm);
myService.Update();
// Create service instances
JobServiceInstance myServiceInstance; // JobServiceInstance is a subclas of SPServiceInstance
foreach (SPServer server in farm.Servers)
{
myServiceInstance = new JobServiceInstance(server, myService);
myServiceInstance.Update();
}
}
// Dayly schedule
SPDailySchedule schedule = new SPDailySchedule();
schedule.BeginHour = 1;
schedule.EndHour = 1;
schedule.BeginMinute = 0;
schedule.EndMinute = 59;
// Our own job; JobCheckDocDates is a subclass of SPJobDefinition
JobCheckDocDates newJob = new JobCheckDocDates(cegService, null, SPJobLockType.Job);
newJob.Schedule = schedule;
newJob.Update();
myService.JobDefinitions.Add(newJob);
myService.Update();
}
catch (Exception e)
{
Logger.Error("[" + properties.Feature.Definition.DisplayName + "] Error during feature activation", e);
}
}
Điều này tạo ra một dịch vụ có sẵn trên tất cả các máy chủ trong trang trại.
Một số chi tiết trên lớp con:
public class JobCheckDocDates: Common.BaseJob
{
/// <summary>
/// The job name
/// </summary>
public static string JobName = "XXX job";
/// <summary>
/// Constructor
/// </summary>
public JobCheckDocDates() : base() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="service"></param>
/// <param name="server"></param>
/// <param name="lockType"></param>
public JobCheckDocDates(SPService service, SPServer server, SPJobLockType lockType)
: base(JobName, service, server, lockType) { }
...
và tất nhiên các phương pháp Execute.
public class JobService : SPService
{
public static string XXXServiceName = "XXX Service";
public override string DisplayName
{
get
{
return XXXServiceName;
}
}
public override string TypeName
{
get
{
return "XXX Service Type";
}
}
/* An empty public constructor required for serialization. */
public JobService() { }
public JobService(SPFarm farm)
: base(XXXServiceName, farm)
{
}
}
public class JobServiceInstance : SPServiceInstance
{
/// <summary>
/// Eos Service Instance Name
/// </summary>
public static string XXXServiceInstanceName = "XXXServiceInstance";
/// <summary>
/// Manage Link
/// </summary>
private SPActionLink _manageLink;
/// <summary>
/// Provision Link
/// </summary>
private SPActionLink _provisionLink;
/// <summary>
/// Unprovision Link
/// </summary>
private SPActionLink _unprovisionLink;
/// <summary>
/// Roles
/// </summary>
private ICollection<string> _roles;
/// <summary>
/// Manage Link
/// </summary>
public override SPActionLink ManageLink
{
get
{
if (_manageLink == null)
{
_manageLink = new SPActionLink(SPActionLinkType.None);
}
return _manageLink;
}
}
/// <summary>
/// Provision Link
/// </summary>
public override SPActionLink ProvisionLink
{
get
{
if (_provisionLink == null)
{
_provisionLink = new SPActionLink(SPActionLinkType.ObjectModel);
}
return _provisionLink;
}
}
/// <summary>
/// Unprovision Link
/// </summary>
public override SPActionLink UnprovisionLink
{
get
{
if (_unprovisionLink == null)
{
_unprovisionLink = new SPActionLink(SPActionLinkType.ObjectModel);
}
return _unprovisionLink;
}
}
/// <summary>
/// Roles
/// </summary>
public override ICollection<string> Roles
{
get
{
if (_roles == null)
{
_roles = new string[1] { "Custom" };
}
return _roles;
}
}
/// <summary>
/// Empty constructor
/// </summary>
public JobServiceInstance() : base() { }
/// <summary>
/// Constructor
/// </summary>
/// <param name="server">The server</param>
/// <param name="service">The Eos service</param>
public JobServiceInstance(SPServer server, JobService service)
: base(XXXServiceInstanceName, server, service)
{
}
Hiện tại, trong Trung tâm quản trị, đi tới Hoạt động/Dịch vụ trên máy chủ. Chọn máy chủ mong muốn và khởi động dịch vụ.
Để trả lời danh sách câu hỏi của bạn: 1. Triển khai giải pháp chỉ một lần, độc lập với WFE. 2. Vì đối tượng địa lý có phạm vi trang trại nên được kích hoạt trong Trung tâm quản trị. 3. SPJobLockType là SPJobLockType.Job
Đây không phải là những gì bạn tưởng tượng, nhưng nó có lợi thế cho phép bạn dễ dàng chọn nơi công việc được chạy, thậm chí lâu sau khi bạn cài đặt tính năng này (ví dụ: nếu máy chủ trở thành quá tải với các thứ khác).
Phương pháp OnFeatureActivated có thể thông minh hơn và kiểm tra từng máy chủ nếu dịch vụ tồn tại và thêm nó nếu cần. Nhưng việc xóa dịch vụ từ mọi dịch vụ trong OnFeatureDeactivated trở nên đơn giản hơn. Vì vậy, nếu bạn thêm máy chủ mới, hãy tắt kích hoạt rồi kích hoạt lại tính năng.