Unlike a custom actions, workflows in Dynamics CRM are uniquely identified  by their id (‘WorkflowId’) and not by their name. You can either query the workflow entity in CRM to retrieve the WorkflowId dynamically or you could hard-code the id in your program. The WorkflowId won’t ever change, even if you move between organizations. Performance wise it’s a best practice to use the hard-coded WorkflowId in your code, as this prevents an extra request to the system. Keep in mind to add a small comment in your code with the name of the Workflow so your code stays readable.

How to find the WorkflowId

Static

The easiest option to find the WorkflowId is to open the Workflow editor and extract the WorkflowId form the address bar. The WorkflowId is located between ‘%7b’ and ‘%7d’ which stand for URL encoded ‘{‘ and ‘}’ respectively.WorkflowEditor_WorkflowId

Dynamically using a query

You can also retrieve the WorkflowId dynamically by using code. Keep in mind that the name of a workflow is not unique. You should provide as many criteria as possible to make sure you retrieve the correct WorkflowId. For example you could check for it’s primary entity.

It’s also important to know that each time you revise a workflow in CRM, it creates a new workflow entry in the workflow table with the same name! So when you start looking for your workflow by name, it will return multiple records. You should query for the workflow of type ‘definition’ and parentworkflowid should be empty.

Example code:

QueryExpression workflowQuery = new QueryExpression("workflow");
workflowQuery.TopCount = 1;
workflowQuery.NoLock = true;
workflowQuery.ColumnSet = new ColumnSet("workflowid");
workflowQuery.Criteria.AddCondition(new ConditionExpression("name", ConditionOperator.Equal, "WorkflowName"));
workflowQuery.Criteria.AddCondition(new ConditionExpression("type", ConditionOperator.Equal, 1)); //Definition
workflowQuery.Criteria.AddCondition(new ConditionExpression("parentworkflowid", ConditionOperator.Null);
workflowQuery.Criteria.AddCondition(new ConditionExpression("primaryentity", ConditionOperator.Equal, "quote"));
EntityCollection workflowCollection = service.RetrieveMultiple(workflowQuery);

Execute the workflow from C#

To execute a workflow from C# we need to execute a message, an ExecuteWorkflowRequest message.

Example code:

tracing.Trace("GenerateDocument started.");
ExecuteWorkflowRequest generateDocRequest = new ExecuteWorkflowRequest()
{
    WorkflowId = Guid.Parse("EE4B3CE6-5E0E-470B-9760-42882CECA562"), //Generate document on Quote entity
    EntityId = record.Id
};

try
{
    ExecuteWorkflowResponse response = service.Execute(generateDocRequest) as ExecuteWorkflowResponse;
}
catch (Exception ex)
{
    tracing.Trace(ex.ToString());
    throw new InvalidPluginExecutionException("QUOTE_ERROR_DOCUMENT_GENERATION");
}
tracing.Trace("GenerateDocument Finished.");

You workflow is now scheduled for execution (background workflow) or executed immediately (real-time workflow).

Leave a Reply