SharePoint: Cancelling or Terminating Workflows using C# and CSOM
There are a number of good articles on the Client Side Object Model, but I couldn't find an example for cancelling or terminating workflows. (I'm not sure what the difference is, but I'll update the article if I find out.)
https://msdn.microsoft.com/en-us/library/office/Dn481315.aspx
It seems like we need two different techniques for handling SharePoint 2013 workflows and SharePoint 2010 workflows running in SharePoint 2013. Here's an article on that architecture.
https://msdn.microsoft.com/en-us/library/office/jj163181.aspx
This code may run into issues when the Workflow History list grows to over 5000 items. This article will be updated when a solution has been tested.
It is not clear whether this code will cancel or terminate Nintex Workflows. More testing to be done.
using Microsoft.SharePoint.Client;
using Microsoft.SharePoint.Client.Workflow;
using Microsoft.SharePoint.Client.WorkflowServices;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace CancelWorkflows
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine("URL:" + args[0]);
Console.WriteLine("List:" + args[1]);
if (args.Length == 0)
{
Console.WriteLine("Enter a url and list name. Use quotes if there are spaces.");
}
if (args[0] == "/?")
{
Console.WriteLine("Enter a url and a Workflow History list name. Use quotes if there are spaces.");
Console.WriteLine(@"Example: https://demosite/" "Workflow History""");
}
ClientContext context = new ClientContext(args[0]);
Web web = context.Web;
context.Load(web);
context.ExecuteQuery();
Console.WriteLine(web.Url);
var wfServicesManager = new Microsoft.SharePoint.Client.WorkflowServices.WorkflowServicesManager(context, web);
InteropService interopService = wfServicesManager.GetWorkflowInteropService();
ListCollection listCollection = web.Lists;
context.Load(listCollection);
context.ExecuteQuery();
foreach (List list in listCollection)
{
if (list.Title.Contains(args[1])) {
context.Load(list, l => l.Title);
context.ExecuteQuery();
Console.WriteLine("List:" + list.Title);
CamlQuery camlQuery = new CamlQuery();
camlQuery.ViewXml =
@"<View></View>";
ListItemCollection listItemCollection = list.GetItems(camlQuery);
context.Load(listItemCollection);
context.ExecuteQuery();
Console.WriteLine("First cancel SharePoint 2010 Workflows");
foreach (ListItem listItem in listItemCollection)
{
if ((listItem["Event"].ToString() == "1") || (listItem["Event"].ToString() == "10") || (listItem["Event"].ToString() == "11"))
{
Console.WriteLine(listItem["WorkflowInstance"]);
Console.WriteLine(listItem["Event"]);
Guid workflowInstanceGuid;
Guid.TryParse(listItem["WorkflowInstance"].ToString(), out workflowInstanceGuid);
interopService.CancelWorkflow(workflowInstanceGuid);
context.ExecuteQuery();
}
}
Console.WriteLine("Next cancel SharePoint 2013 Workflows");
WorkflowSubscriptionService workflowSubscriptionService = wfServicesManager.GetWorkflowSubscriptionService();
WorkflowSubscriptionCollection workflowSubscriptionCollection = workflowSubscriptionService.EnumerateSubscriptions();
context.Load(workflowSubscriptionCollection);
context.ExecuteQuery();
WorkflowInstanceService workflowInstanceService = wfServicesManager.GetWorkflowInstanceService();
foreach (WorkflowSubscription workflowSubscription in workflowSubscriptionCollection)
{
Console.WriteLine("workflowSubscription: " + workflowSubscription.Name);
WorkflowInstanceCollection workflowInstanceCollection = workflowInstanceService.Enumerate(workflowSubscription);
context.Load(workflowInstanceCollection);
context.ExecuteQuery();
foreach (WorkflowInstance workflowInstance in workflowInstanceCollection)
{
Console.WriteLine(workflowInstance.Properties["Microsoft.SharePoint.ActivationProperties.ItemId"] + ": " + workflowInstance.Status);
//workflowInstanceService.CancelWorkflow(workflowInstance);
workflowInstanceService.TerminateWorkflow(workflowInstance);
context.ExecuteQuery();
}
context.Load(workflowInstanceCollection);
context.ExecuteQuery();
foreach (WorkflowInstance workflowInstance in workflowInstanceCollection)
{
Console.WriteLine(workflowInstance.Properties["Microsoft.SharePoint.ActivationProperties.ItemId"] + ": " + workflowInstance.Status);
}
}
}
}
Console.WriteLine("Done.");
Console.ReadLine();
} }}