El Blanco's Office 2007 Blog

Wednesday, May 07, 2008

Checking if a Workflow is Running on an Item / SPWorkflowState

I needed to write some code that checked whether or not a workflow was running on a SPListItem. At first I came up with the following:

SPListItem item = ...;
foreach (SPWorkflow wf in item.Workflows)
{
    if (wf.InternalState == SPWorkflowState.Running)
    {
        // do whatever you want . . .
    }
}


The problem with this is that a workflow instance can have many states represented as a bitwise AND of all current states. The SPWorkflowState enumeration has the following values:

None

0

000000000000

Locked

1

000000000001

Running

2

000000000010

Completed

4

000000000100

Cancelled

8

000000001000

Expiring

16

000000010000

Expired

32

000000100000

Faulting

64

000001000000

Terminated

128

000010000000

Suspended

256

000100000000

Orphaned

512

001000000000

HasNewEvents

1024

010000000000

NotStarted

2048

100000000000

All

4095

111111111111


e.g. if a workflow instance was Running and Locked (not sure if this is an actual possible combination, but it serves as an example !) then the workflow's internal state would have a value of 3 representing the values of the Running AND Locked states.

To see if a workflow instance is running or not you need to perform a bitwise AND of the workflow instance's internal state with the SPWorkflowState you're interested in. To assist with this, I used the helper method shown below:

bool WorkflowStatePresent(int wfState, int stateToCheckFor)
{
    bool statePresent = false;
    if ((wfState & stateToCheckFor) == stateToCheckFor)
        statePresent = true;
    return statePresent;
}


I then invoke this as follows:

foreach (SPWorkflow wf in item.Workflows)
{
    if (WorkflowStatePresent((int)wf.InternalState,(int)SPWorkflowState.Running)
    {
        // do whatever you want . . .
    }
}