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 . . .
}
}