Archive for the ‘SharePoint Designer 2010’ Category

HOWTO: Start a SharePoint 2010 Workflow Programatically

July 15, 2010

UPDATE – 26-Aug-2011

I just noted this on the Microsoft SharePoint Development Blog which, while not solving the problem, might be a different way to tackle it:

Calling SharePoint workflow instances programmatically from other SharePoint workflows

 

ORIGINAL POST

I needed to automate some workflow creation from a Windows client application, and there is a web service available for this purpose. First introduced in SharePoint 2007 (*not* in WSS 3.0!), the workflow.asmx web service allows you to programatically start a workflow.

Starting a Workflow Programatically (C#)

SharePoint 2010 includes a number of out-of-the-box workflows, but you can also use SharePoint Designer 2010 or Visual Studio .NET 2008/2010 (for Windows Workflow Foundation) to create your own customised workflows. In this example I will use SharePoint Designer 2010.

The following is required to start the workflow:
1. The Uri for the list item (or page) you want to start the workflow on; and
2. the Template Id for the workflow
and optionally:
3. The xml workflow initiation data (see below)

The Uri should be simple to get, but the Template Id isn’t as easy. If you use SharePoint Designer 2010, there doesn’t appear to be any way to retrieve the Template Id. So you either have to get it via code, or as a quick work-around use the SharePoint site itself. You can get the Template Id via:
1. Go to the list/library that the workflow is attached to (ASSUMPTION: you are using a workflow that applies to a list item/page)
2. Hilight an item in the list
3. In the Ribbon, Library Tools, Documents tab, click “Workflows”
4. In the “Start a New Workflow” section, right-click on the url that has the name of your workflow and select “Copy Shortcut”
5. Look at the Url and extract the Guid from the TemplateId parameter. For example, in this url:

http://mysharepointsite/_layouts/IniWrkflIP.aspx?List={21303f3e-d36c-40f2-806e-0d2536b4ec72}&ID=4&TemplateID={aed94889-39bc-4eb9-997b-302d0f55c645}&Source=http%3A%2F%2Febs3%2FTest%25201%2FForms%2FAllItems%2Easpx

the Template Id can be found in: “TemplateID={aed94889-39bc-4eb9-997b-302d0f55c645}”.
6. Copy the Guid for later use

You are now ready to start your workflow.

In Visual Studio 2008/2010:
1. Create a new project (i.e. win-forms or command-line)
2. Add a reference to the workflow.asmx web service (http://mysharepointsite/_vti_bin/workflow.asmx). NOTE: when adding a reference, I had difficulties adding a service reference, so you may need to use the “old-school” approach and add a web reference instead. You can do this by right-clicking on the project and selecting “Add Web Reference…”.
3. Add the following code (WSWorkflow is the name of my web reference class):


// Use workflow web service (old-style)
string _itemUri = "http://mysharepointsite/TestDocs/MyDocument.docx";

Guid workflowTemplateGuid = new Guid("{YOUR-GUID-GOES-HERE}");
WSWorkflow.Workflow workflow = new WSWorkflow.Workflow();

workflow.Credentials = System.Net.CredentialCache.DefaultCredentials;
workflow.StartWorkflow(_itemUri, workflowTemplateGuid, null);

This should start your workflow.

Providing Workflow Initiation Data

SharePoint workflows allow you to create parameters and provide initiation data. When you create a workflow in SharePoint Designer 2010 and publish the workflow, it automatically creates an Infopath form to hold Association and/or Initiation Data (even if your workflow doesn’t have any!).

SharePoint Designer - InfoPath Form

SharePoint Designer - InfoPath form created when the workflow is published

When you add initiation form parameters to your workflow, these are automatically added to your Infopath form. You can click on your Infopath form to see the form and make changes directly within the Infopath designer. Also, the Infopath designer will display the schema for your Infopath form, which is essential to provide Initiation form data to your workflow.

Initiation form parameters in SharePoint Designer 2010

InfoPath 2010 - Data schema for our workflow initiation form

The data schema can then be used to submit initiation form data to our workflow programatically. By changing our workflow call and generating an xml-friendly schema, we can start the workflow with our data.


// Create our xml the old-fashioned way!
string xmlInit =
“<dfs:myFields xmlns:xsd=”http://www.w3.org/2001/XMLSchema&#8221; xmlns:dms=”http://schemas.microsoft.com/office/2009/documentManagement/types&#8221; xmlns:dfs=”http://schemas.microsoft.com/office/infopath/2003/dataFormSolution&#8221; xmlns:q=”http://schemas.microsoft.com/office/infopath/2009/WSSList/queryFields&#8221; xmlns:d=”http://schemas.microsoft.com/office/infopath/2009/WSSList/dataFields&#8221; xmlns:ma=”http://schemas.microsoft.com/office/2009/metadata/properties/metaAttributes&#8221; xmlns:pc=”http://schemas.microsoft.com/office/infopath/2007/PartnerControls&#8221; xmlns:xsi=”http://www.w3.org/2001/XMLSchema-instance”><dfs:queryFields /><dfs:dataFields><d:SharePointListItem_RW><d:myname>Gavin McKay</d:myname></d:SharePointListItem_RW></dfs:dataFields></dfs:myFields>”;

XmlDocument xmlDoc = new XmlDocument();
xmlDoc.LoadXml(xmlInit);

// Use workflow web service (old-style)
string _itemUri = “http://mysharepointsite/TestDocs/MyDocument.docx&#8221;;
Guid workflowTemplateGuid = new Guid("{YOUR-GUID-GOES-HERE}");
WSWorkflow.Workflow workflow = new WSWorkflow.Workflow();

workflow.Credentials = System.Net.CredentialCache.DefaultCredentials;
workflow.StartWorkflow(_itemUri, workflowTemplateGuid, xmlDoc.DocumentElement); // Pass your xml in here

You can review the results of your workflow from within SharePoint.

Final Notes
There are better ways to submit the Xml data (such as by a class that can be serialized into the initiation form format), and plenty of debugging capabilities both within SharePoint (log files and workflow status) and via SharePoint Designer (adding log history actions to your workflow to record initiation form data). But hopefully that is a good start!

Guid workflowTemplateGuid = new Guid(“{aed94889-39bc-4eb9-997b-302d0f55c645}”);