SharePoint workflow is a essence to that platform and I many cases is a main reason to implement it.  Today I would like you to show you how to run SharePoint workflow from Console application. In case of SharePoint on premise is not something big, as we have a few options here like Timer Job. But when we work with SharePoint online is priceless. I know that from personal experience of last few weeks. Let’s imagine that we written SharePoint workflow, which resets statuses of some items on a list. Unfortunately when we work in cloud we don’t have a option to schedule the job. Option which comes up here for us is console application which will start the process. Then we can publish it as Azure WebJob, and Azure scheduler will run it every day in the morning. It’s really simple and efficient.

Configure application to work with SharePoint online

In first step we have to create token which will be used to authenticate our application. I have written a post how to do this here , so I will not write it again in details. In the next step we should create simple console application with Visual Studio and install with NuGet Package Manager AppForSharePointWebToolkit. We should configure it as described in the post, to grant access our application access to Office 365 tenant.

Method to start SharePoint workflow

First element is reference to „Microsoft.SharePoint.Client.WorkflowServices”. It contains necessary classes to work with our workflow.

WorkflowServices
WorkflowServices

Below you can find the code which make everything for us. In general we have four main blocks here.
style=”background-color: lightgrey;”

  1. We get ClientContext for our site where workflow is located
  2. We are searching for workflow instance
  3. We build a list of list items
  4. We run workflow for each list item

And that’s all. There are also two important thing from my point of view:

  • capse in CamlQuary  should be raplaced with  _x0020_  . In other case our query will not work
  • We have to provide workflow name in our site collection to start valid process
  private static void RunReminder(ClientContext clientContext)
 {
 Web web = clientContext.Web;
 WorkflowServicesManager wfServicesManager = new WorkflowServicesManager(clientContext, web);
 WorkflowDeploymentService wfDeploymentService = wfServicesManager.GetWorkflowDeploymentService();
 WorkflowDefinitionCollection wfDefinitionCollection = wfDeploymentService.EnumerateDefinitions(false);
 clientContext.Load(wfDefinitionCollection, wfDefs => wfDefs.Where(wfd => wfd.DisplayName == "Reminder"));
 clientContext.ExecuteQuery();
 WorkflowDefinition wfDefinition = wfDefinitionCollection.First();

 var workflowSubscriptionService = wfServicesManager.GetWorkflowSubscriptionService();
 var workflowAssociations = workflowSubscriptionService.EnumerateSubscriptionsByDefinition(wfDefinition.Id);
 clientContext.Load(workflowAssociations);
 clientContext.ExecuteQuery();

 var firstWorkflowAssociation = workflowAssociations.First();
 var workflowInstanceService = wfServicesManager.GetWorkflowInstanceService();
 var startParameters = new Dictionary<string, object>();

 List employeesList = clientContext.Web.Lists.GetByTitle("Employees");
 CamlQuery query = new CamlQuery();
 query.ViewXml = "<View><Query><Where>" +
 "<And>" +
 "<Contains>" +
 "<FieldRef Name='Lunch_x0020_Ordered'/><Value Type='Boolean'>0</Value>" +
 "</Contains>" +
 "<Contains>" +
 "<FieldRef Name='Out_x0020_of_x0020_office'/><Value Type='Boolean'>0</Value>" +
 "</Contains>" +
 "</And>" +
 "</Where></Query></View>";
 ListItemCollection collection = employeesList.GetItems(query);
 clientContext.Load(collection);

 try
 {
 clientContext.ExecuteQuery();
 }
 catch (Exception exception)
 {

 Console.WriteLine("There were exception on a list: " + exception.Message + "Application will be terminated!!!");
 Environment.Exit(1);
 }
 foreach (var item in collection)
 {
 Console.WriteLine("starting first workflow on " + item.Id);
 workflowInstanceService.StartWorkflowOnListItem(firstWorkflowAssociation, item.Id, startParameters);
 clientContext.ExecuteQuery();
 }

 clientContext.Dispose();
 }

If you are interested in SharePoint development here are other useful articles for you: