Summit 7 Team Blogs

Identifying Custom SharePoint Designer Workflows

Picture of SPD-2010

I had a case recently where I needed to find all workflows within a SharePoint 2007 farm where there were custom workflows created using SharePoint Designer 2007. In this scenario, there were no custom workflows created through Visual Studio so I could be confident that if a workflow was identified as custom, it was created using SharePoint Designer. One simple way to identify this is through the use of properties of the SPWorkflowAssociation object for the workflow that is associated to a SPList or SPContentType.

When creating an instance of a workflow through the SharePoint web interface, you must select one of the base template types, such as the “Approval” or “Collect Feedback” workflow, for the baseline of your workflow instance. When you create a custom workflow through SharePoint Designer, you are not selecting a baseline template for the workflow therefor, in code, the SPWorkflowAssociation.BaseTemplate value for the custom workflow will be null. By verifying the value of this property, it is a good indication that the workflow is custom and, in my case, was created with SPD.

You can further verify the existence of a custom workflow by checking the existence of an “Xoml” reference within the SPWorkflowAssociation.InternalName property. In a typical out of the box workflow, the InternalName property for the workflow association would be something similar to “Approval” or “Collect Feedback”. When custom workflows are created through SPD, there is a set of XML markup files that are created which manage the rules and configuration of the workflow and also tie the workflow to a specific SPList. The InternalName property contains references to this Xoml so by simply searching this property for the existence of “Xoml”, your can be assured that you are working with a custom workflow.

Lastly, another property on the workflow association that warrants mention is the SPWorkflowAssociation.Enabled property. As modifications are made to custom workflows within SharePoint Designer, there is a version history that is maintained for that workflow. As workflow modifications are made and published, previous versions of a workflow are disabled to ensure that only the latest version is executed. As you iterate through the SPWorkflowAssociations related to an SPList or SPContentType, you can appropriately find the most current workflow with the Enabled property.

The following simple code snippet will iterate a SPList and identify the custom workflows:

<span class="lnum"> 1: </span><span class="kwrd">using</span> System;
<span class="lnum"> 2: </span><span class="kwrd">using</span> System.Collections.Generic;
<span class="lnum"> 3: </span><span class="kwrd">using</span> System.Text;
<span class="lnum"> 4: </span><span class="kwrd">using</span> Microsoft.SharePoint;
<span class="lnum"> 5: </span><span class="kwrd">using</span> Microsoft.SharePoint.Workflow;
<span class="lnum"> 6: </span>
<span class="lnum"> 7: </span><span class="kwrd">namespace</span> SampleWorkflowDiscoveryApp
<span class="lnum"> 8: </span>{
<span class="lnum"> 9: </span>  <span class="kwrd">class</span> Program
<span class="lnum"> 10: </span>  {
<span class="lnum"> 11: </span>    <span class="kwrd">static</span> <span class="kwrd">void</span> Main(<span class="kwrd">string</span>[] args)
<span class="lnum"> 12: </span>    {
<span class="lnum"> 13: </span>      <span class="kwrd">using</span> (SPSite site
<span class="lnum"> 14: </span>                 = <span class="kwrd">new</span> SPSite(<span class="str">"http://contoso.com"</span>))
<span class="lnum"> 15: </span>      {
<span class="lnum"> 16: </span>        <span class="kwrd">using</span> (SPWeb web = site.OpenWeb())
<span class="lnum"> 17: </span>        {
<span class="lnum"> 18: </span>          SPList list = web.Lists[<span class="str">"TestList"</span>];
<span class="lnum"> 19: </span>          <span class="kwrd">foreach</span> (SPWorkflowAssociation wfAssoc <span class="kwrd">in</span> list.WorkflowAssociations)
<span class="lnum"> 20: </span>          {
<span class="lnum"> 21: </span>            <span class="rem">// Not interested in previous </span>
<span class="lnum"> 22: </span>            <span class="rem">// versions of workflows</span>
<span class="lnum"> 23: </span>            <span class="kwrd">if</span> (wfAssoc.Enabled)
<span class="lnum"> 24: </span>            {
<span class="lnum"> 25: </span>              <span class="kwrd">if</span> (wfAssoc.BaseTemplate == <span class="kwrd">null</span> &amp;&amp;
<span class="lnum"> 26: </span>                   wfAssoc.InternalName.Contains(<span class="str">"Xoml"</span>))
<span class="lnum"> 27: </span>              {
<span class="lnum"> 28: </span>                <span class="rem">// Identified a custom workflow</span>
<span class="lnum"> 29: </span>                <span class="rem">// Add more logic here...</span>
<span class="lnum"> 30: </span>              }
<span class="lnum"> 31: </span>              <span class="kwrd">else</span>
<span class="lnum"> 32: </span>              {
<span class="lnum"> 33: </span>                <span class="rem">// Out of the box workflow</span>
<span class="lnum"> 34: </span>              }
<span class="lnum"> 35: </span>            }
<span class="lnum"> 36: </span>          }
<span class="lnum"> 37: </span>        }
<span class="lnum"> 38: </span>      }
<span class="lnum"> 39: </span>    }
<span class="lnum"> 40: </span>  }
<span class="lnum"> 41: </span>}

Hopefully this will save you some of the time that I spent locating the best approach for identifying custom workflows.




The sample scripts are not supported under any Summit 7 Systems standard support program or service. The sample scripts are provided AS IS without warranty of any kind. Summit 7 Systems further disclaims all implied warranties including, without limitation, any implied warranties of merchantability or of fitness for a particular purpose. The entire risk arising out of the use or performance of the sample scripts and documentation remains with you. In no event shall Summit 7 Systems, its authors, or anyone else involved in the creation, production, or delivery of the scripts be liable for any damages whatsoever (including, without limitation, damages for loss of business profits, business interruption, loss of business information, or other pecuniary loss) arising out of the use of or inability to use the sample scripts or documentation, even if Summit 7 Systems has been advised of the possibility of such damages.