Starting/Canceling a SharePoint Designer workflow programmatically
I had enough trying to find this code, so I'm putting what I've pieced together to activate a workflow programmatically (specifically a SharePoint Designer Workflow)
public static string StartWorkflow(ContractListItem contract, string workflowName) { SPListItem wfListItem = contract.ListItem; SPWorkflowAssociationCollection wfAssocs = wfListItem.ParentList.WorkflowAssociations; SPWorkflowAssociation activeWorkflowAssoc = null; string errorMessage = string.Empty; foreach (SPWorkflowAssociation wfAssoc in wfAssocs) { if (wfAssoc.Name.Equals(workflowName)) { activeWorkflowAssoc = wfAssoc; break; } } // if the workflow exists, start the workflow SPWorkflow activeWorkflow = null; if (activeWorkflowAssoc != null) { try { activeWorkflow = SPContext.Current.Site.WorkflowManager.StartWorkflow( wfListItem, activeWorkflowAssoc, "<Data></Data>"); } catch (Exception ex) { ErrorHandler.LogError(Resources.ActionBarWebPart_WorkflowNotStarted, ex); if (activeWorkflow != null) SPWorkflowManager.CancelWorkflow(activeWorkflow); errorMessage = Resources.ActionBarWebPart_WorkflowNotStarted; } } else { ErrorHandler.LogError(Resources.ActionBarWebPart_WorkflowDoesNotExist); errorMessage = Resources.ActionBarWebPart_WorkflowDoesNotExist; } return errorMessage; } }
Comments
Anonymous
January 25, 2009
This one is an awesome feature to add if you've got an application running a workflow asynchronouslyAnonymous
June 09, 2009
Hi Suman, great post A few day's ago I also wrote a post about this. There is one thing you forgot that is checking if the workflow isn't already running for the item. This can cause a exception when you start the workflow. you can read about it here: http://www.blogaboutsharepoint.com/2009/06/08/starting-a-workflow-trough-code/Anonymous
October 01, 2014
Best is to stop the workflow, then start it. Stopping it, after getting your SPWeb and your SPListItem: private bool StopWF(SPListItem myItem, SPWeb web) { web.AllowUnsafeUpdates = true; SPWorkflowCollection itemWFColl = myItem.Workflows; foreach (SPWorkflow itemWF in itemWFColl) { if (itemWF.InternalState == SPWorkflowState.Running) { SPWorkflowManager.CancelWorkflow(itemWF); return true; } } return false; } Starting it, after getting your SPSite, SPWeb, and then SPListItemCollection via CAML query that contains the item you wish to stop the workflow on: SPWorkflowAssociation assn = myListItemCollection.WorkflowAssociations.GetAssociationByName(wfName, System.Threading.Thread.CurrentThread.CurrentCulture); SPWorkflowManager mgr = site.WorkflowManager; foreach (SPListItem item in myListItemCollection) { bool stopped = StopWF(item, web); if (stopped) { web.AllowUnsafeUpdates = true; mgr.StartWorkflow(item, assn, string.Empty, true); } } Of course you'll want the appropriate try...catch logic, error handling, etc. But that is the meat of it.Anonymous
October 01, 2014
Thanks! I wrote this in 2008, so while it still applies for FTC code, it doesn't happen the same way for CSOM. Maybe I'll post an updated version of this article for CSOM. Cheers!