Executing a Dynamics CRM WorkFlow from a Plugin

As part of a StateFlow engine I writing for a Microsoft Dynamics CRM 2011 project I needed to be able to run a series of custom workflow activities.  I needed the workflow activities to be driven off a configuration entity that would hold rules like, how often to run, what status reason to set a matching record to and so on.  One part that was a bit less than obvious was how to get the GUID for the workflow I wanted to execute in a search by “workflow name”.  I’m sure there are several ways to do this but I was surprised when I found you could query it just like any other entity.  Just be sure that you add a condition of “type”, ConditionOperator.Equal, 1 otherwise CRM will grab the unpublished version of the workflow and throw a error “workflow must be in published state”.

Code Snippets

The following is a code sample that calls two methods: GetProcessId and ExecuteWorkFlow before we can do so we need to get the ID of the workflow which is stored in the PrimaryEntityId attribute of the workflow context.

// Create the context

IWorkflowContext context = executionContext.GetExtension<IWorkflowContext>();

_primaryEntity = context.PrimaryEntityId;

Guid processId = new Guid(GetProcessId(service, “workflow”, “name”, “StateFlow”).Id.ToString());

ExecuteWorkFlow(service, processId, _primaryEntity);

private void ExecuteWorkFlow(IOrganizationService service, Guid workFlowId, Guid entityId)

{

try

{

// Create an ExecuteWorkflow request.

ExecuteWorkflowRequest request = new ExecuteWorkflowRequest()

{

WorkflowId = workFlowId,

EntityId = entityId

};

// Execute the workflow.

ExecuteWorkflowResponse response =

(ExecuteWorkflowResponse)service.Execute(request);

}

catch (Exception ex)

{

throw new InvalidPluginExecutionException();

}

}

 

 

private Entity GetProcessId(IOrganizationService service, string EntityLogicalName, string SearchFieldName, object SearchValue)

//Internal method used to search for entity records

{

EntityLogicalName = EntityLogicalName.ToLower();

SearchFieldName = SearchFieldName.ToLower();

QueryExpression query = new QueryExpression(EntityLogicalName);

query.ColumnSet = new ColumnSet(true);

query.Criteria.AddCondition(new ConditionExpression(SearchFieldName, ConditionOperator.Equal, SearchValue));

query.Criteria.AddCondition(new ConditionExpression(“type”, ConditionOperator.Equal, 1));

try

{

EntityCollection response = service.RetrieveMultiple(query);

if (response != null && response.Entities.Count > 0)

return response.Entities[0];

else { return null; }

}

catch (Exception ex)

{

//Do error hadling

throw ex;

}

}