If you are experiencing this problem, first thing you need to check
is this great post.
If your workflow is not in Visual Studio, rather it's a SPD
workflow, what you can do is create a Timer Job which runs every couple of minutes and set the workflow version. Here is the Code:
 // Feature receiver  
 using System;  
 using System.Runtime.InteropServices;  
 using System.Security.Permissions;  
 using Microsoft.SharePoint;  
 using Microsoft.SharePoint.Security;  
 using Microsoft.SharePoint.Administration;  
 using **.Code.TimerJobs;  
 namespace **.Features.Unlock_Workflow_Tasks  
 {  
 [Guid("***")]  
 public class Unlock_Workflow_Tasks : SPFeatureReceiver  
 {  
 public override void FeatureActivated(SPFeatureReceiverProperties properties)  
 {  
 SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;  
 if (webApp == null)  
 return;  
 try  
 {  
 // make sure the job isn't already registered  
 foreach (SPJobDefinition job in webApp.JobDefinitions)  
 {  
 if (job.Name == JOB_NAME)  
 job.Delete();  
 }  
 }  
 catch  
 {  
 }  
 // install the job  
 UnlockWorkflowTasks timerJobDefinition = new UnlockWorkflowTasks(JOB_NAME, webApp);  
 SPMinuteSchedule schedule = new SPMinuteSchedule();  
 schedule.Interval = 15;  
 schedule.BeginSecond = 0;  
 schedule.EndSecond = 59;  
 timerJobDefinition .Schedule = schedule;  
 timerJobDefinition .Update();  
 }  
 // Uncomment the method below to handle the event raised before a feature is deactivated.  
 public override void FeatureDeactivating(SPFeatureReceiverProperties properties)  
 {  
 SPWebApplication webApp = properties.Feature.Parent as SPWebApplication;  
 // delete the job  
 try  
 {  
 foreach (SPJobDefinition job in webApp.JobDefinitions)  
 {  
 if (job.Name == JOB_NAME)  
 job.Delete();  
 }  
 }  
 catch  
 {  
 }  
 }  
 }  
 }  
 // The Timer Job  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using Microsoft.SharePoint.Administration;  
 using Microsoft.SharePoint;  
 using **.Code.Utilities;  
 using Microsoft.SharePoint.Workflow;  
 namespace **.Code.TimerJobs  
 {  
 class UnlockWorkflowTasks : SPJobDefinition  
 {  
 public UnlockWorkflowTasks(): base() {}  
 public UnlockWorkflowTasks(string jobName, SPWebApplication webApplication)  
 : base(jobName, webApplication, null, SPJobLockType.Job)  
 {  
 this.Title = "**";  
 }  
 public override void Execute(Guid contentDbId)  
 {  
 try  
 {  
 SPSecurity.RunWithElevatedPrivileges(delegate()  
 {  
 using (SPSite site = new SPSite(WebApplication.Sites[0].Url))  
 using (SPWeb web = site.OpenWeb())  
 {  
 UnlockPotentiallyLockedWorkflowTasks(web);  
 }  
 });  
 }  
 catch (Exception ex)  
 {  
 Logger.LogError(ex);  
 }  
 }  
 private void UnlockPotentiallyLockedWorkflowTasks(SPWeb web)  
 {  
 try  
 {  
 web.AllowUnsafeUpdates = true;  
 SPListItemCollection tasks = GetPotentiallyLockedTasks(web);  
 foreach (SPListItem task in tasks)  
 {  
 try  
 {  
 if ((int)task[SPBuiltInFieldId.WorkflowVersion] != 1)  
 {  
 // change it's version to 1.0  
 SPList parentList = task.ParentList.ParentWeb.Lists[new Guid(task[SPBuiltInFieldId.WorkflowListId].ToString())];  
 SPListItem parentItem = parentList.Items.GetItemById((int)task[SPBuiltInFieldId.WorkflowItemId]);  
 SPWorkflow workflow = parentItem.Workflows[new Guid(task[SPBuiltInFieldId.WorkflowInstanceID].ToString())];  
 if (!workflow.IsLocked)  
 {  
 task[SPBuiltInFieldId.WorkflowVersion] = 1;  
 task.SystemUpdate();  
 Logger.LogInfo("Unlock task {0} (ID:{1})", task["Title"].ToString(), task["ID"].ToString());  
 }  
 }  
 }  
 catch (Exception e)  
 {  
 Logger.LogError(e);  
 }  
 }  
 }  
 catch (Exception e)  
 {  
 Logger.LogError(e);  
 }  
 finally  
 {  
 web.AllowUnsafeUpdates = false;  
 }  
 }  
 private SPListItemCollection GetPotentiallyLockedTasks(SPWeb web)  
 {  
 var query = new SPQuery();  
 query.Query = @"  
 <Where>  
 <Neq>  
 <FieldRef Name='Status' />  
 <Value Type='Choice'>Completed</Value>  
 </Neq>  
 </Where>";  
 //query.ViewAttributes = "Scope=\"Recursive\"";  
 return web.Lists[WORKFLOW_TASKS_LIST].GetItems(query);  
 }  
 }  
 }  
No comments:
Post a Comment