2010-06-01 38 views

回答

7

看起來您需要一個農場範圍的功能,它安裝運行此作業的服務。我是這麼做的(使用由同事編寫的代碼,說實話,但他不在SO中)。

使用功能事件接收器創建feature.xml文件。

<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> 

裏面的事件接收器:

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); 
      } 
     }   

這產生了場中的每臺服務器上可用的服務。

在子類中更多的細節:

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) { } 

...

過程和執行方法。

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) 
     { 
     } 

現在,在Central Admin中,轉到服務器上的Operations/Services。選擇所需的服務器並啓動服務。

回答您的問題列表: 1.僅部署一次解決方案,而不依賴於WFE。 2.由於該功能是服務器場範圍,因此應在中央管理中激活。 3. SPJobLockType是SPJobLockType.Job

這不正是你想象的東西,但它有讓您輕鬆選擇作業在哪裏運行,即使長時間在安裝功能後(例如,如果一臺服務器變成優勢與其他東西超載)。

OnFeatureActivated方法可能更智能,並檢查每個服務器是否存在服務,並在需要時添加它。但是從OnFeatureDeactivated中的每個服務中刪除服務會更簡單。所以,如果您添加新的服務器,請取消激活然後重新激活該功能。