3
votes

i've been trying to stop a workflow programmatically. I've read both in various posts and in the msdn that this can be done by updating the Asyncoperation status via update request. However everytime i update the request. the workflow get stuck on a mid stage such as cancelling or pausing and dosen't reach a final state.

any ideas?

protected void ExecutePostAccountUpdate(LocalPluginContext localContext)
    {
        if (localContext == null)
        {
            throw new ArgumentNullException("localContext");
        }

        string fetchXML = "<fetch mapping='logical' count='50' version='1.0'>" +
                          "<entity name='asyncoperation'>" +
                          "<filter>" +
                          "<condition attribute='regardingobjectid' operator='eq' value='" +
                          localContext.PluginExecutionContext.PrimaryEntityId + "' />" +
                          "</filter>" +
                          "</entity>" +
                          "</fetch>";
        EntityCollection col = localContext.OrganizationService.RetrieveMultiple(new FetchExpression(fetchXML));
        if (col.Entities.Count > 0)
        {
            AsyncOperation a = (AsyncOperation)col[0];
            a.StateCode = AsyncOperationState.Completed;
            a.StatusCode = new OptionSetValue(32);
            localContext.OrganizationService.Update(a);



        }

    }
3
Do you mean you're trying to abort a workflow from code within that workflow, or do you mean, abort a workflow 'from the outside', like in a separate bit of code? Might be worth posting some example code of what you've got so far.Alec
Hey alec, i added the sample code, i'm trying to abort it from outside the workflow, in this case i try from a plugin. thanksEranser
StateCode and StatusCode don't usually respond too well to generic updates. Have you tried issuing a SetStateRequest instead?Peter Majeed
no, in the msdn is it written to use update, msdn.microsoft.com/en-us/library/gg309288.aspx but i have found out what happened, changing a workflow state dosen't stop it. the workflow continues to run no matter what the new state is. but in the end of the process there will be an indication to what the final state is.Eranser

3 Answers

1
votes

Have a look at my blog: How to Cancel Workflow Programmatically using C#

Make sure the user have permissions to Cancel System Jobs.

1
votes
QueryExpression queryExpression = new QueryExpression("asyncoperation") { ColumnSet = new ColumnSet("statuscode") };
        queryExpression.Criteria.AddCondition("name", ConditionOperator.Equal, Name of Workflow);
        queryExpression.Criteria.AddCondition("regardingobjectid", ConditionOperator.Equal, regardingobjectId);
        var asyncOperations = organizationService.RetrieveMultiple(queryExpression);

        foreach (var asyncOperation in asyncOperations.Entities)
        {
            if (((OptionSetValue)asyncOperation["statuscode"]).Value == 10 || // Waiting
                ((OptionSetValue)asyncOperation["statuscode"]).Value == 20 || // In Process
                ((OptionSetValue)asyncOperation["statuscode"]).Value == 0)
            {
                Entity operation = new Entity("asyncoperation")
                {
                    Id = asyncOperation.Id,
                    ["statecode"] = new OptionSetValue(3),
                    ["statuscode"] = new OptionSetValue(32)
                };

                organizationService.Update(operation);
            }
        }

Make sure the user have permissions to Cancel System Jobs.

0
votes

It seems you can un-publish a workflow via code, according to this post.

NOTE: This does not necessarily halt an in-progress workflow, but it will prevent any new workflows of that type from being started.

const int WorkflowStatusDraft = 1;
const int WorkflowStatusPublished = 2;

public void PublishWorkflow(Guid workflowId)
{
    SetStateWorkflowRequest publishRequest = new SetStateWorkflowRequest();
    publishRequest.EntityId = workflowId;
    publishRequest.WorkflowState = WorkflowState.Published;
    publishRequest.WorkflowStatus = WorkflowStatusPublished;

    this.CrmService.Execute(publishRequest);
}

public void UnpublishWorkflow(Guid workflowId)
{
    SetStateWorkflowRequest unpublishRequest = new SetStateWorkflowRequest();
    unpublishRequest.EntityId = workflowId;
    unpublishRequest.WorkflowState = WorkflowState.Draft;
    unpublishRequest.WorkflowStatus = WorkflowStatusDraft;

    this.CrmService.Execute(unpublishRequest);
}