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();
        }     }}