3 minute read

Within SharePoint there can be situation in which you would like to start a workflow through code, like in an event receiver. But how do you start a workflow trough code? In the following minutes I will explain how you can accomplish this.

Before you can start a workflow you will have to have a SPListItem for which you want to start the workflow and something to retrieve the SPWorkflowAssociation with. In this example we will use the BaseID of the workflow. The BaseID of a workflow is defined in the elements manifest of the workflow feature.

If you have the two properties you ready to think about the restrictions you have when you start a workflow. The restriction is that a workflow can only be started once on an item. If it is already running and you still try to activate it you will get an exception (Exception from HRESULT: 0×8102009B).

This means that before we can start the workflow we have to check if the workflow isn’t running. In the code block below you see a method for this.

Important: In this method is written with an extension for the .Net Framework called Linq. If you want to use Linq you will have to build your project as a 3.5 Framework project and add a Reference to System.Linq.dll.

 public static SPWorkflowAssociation GetWorkflowAssociationByID(SPList list, Guid id)
 {
    var query = from SPWorkflowAssociation asso in list.WorkflowAssociations
                    where asso.BaseId == id
                    select asso;

    return query.FirstOrDefault();
 } 

In the above method we use a query to find a workflow based on the BaseID. With the SPWorkflowState.Running we check if the workflow is running.
After the executing of the query we have the results and check if it has objects. If there are more than zero SPWorkflow objects in the results a workflow with our BaseID is currently running.

When we have checked this we will have to find the SPWorkflowAssociation of our workflow so that we can start the workflow with this association.
The workflow association can also be find with the BaseID.

 public static SPWorkflowAssociation GetWorkflowAssociationByID(SPList list, Guid id)
 {
    var query = from SPWorkflowAssociation asso in list.WorkflowAssociations
                    where asso.BaseId == id
                    select asso;

    return query.FirstOrDefault();
 } 

In the above method we find the workflow association with the BaseID on the list of the item and return the first or default. We return the first or default because there can only be one association and it will return null by default when there are no associations.

Important: If you want to start a workflow trough code the workflow has to be associated with the parent list of the item.

After performing these actions we can finally start our workflow.

 public static void StartWorkflow(SPItem item, Guid BaseID){
    SPList list = item.ParentList;
    SPWeb web = item.ParentList.ParentWeb;

    if(!IsWorkflowRunning(item, BaseID){
       SPWorkflowAssociation workflowAsso = GetWorkflowAssociationByID(list, BaseID);

       if(workflowAsso != null){
          web.Site.WorkflowManager.StartWorkflow(item, workflowAsso, "");
       }
    }