La siguiente es una página de aplicación de SharePoint que permite cancelar todos los flujos de trabajo activos. Para ejecutarla, debe estar almacenada en la siguiente carpeta (o en una subcarpeta):
C:Program FilesCommon Filesmicrosoft sharedWeb Server Extensions12TEMPLATELAYOUTS
Algunas consideraciones a tener en cuenta:
- Esta página sólo cancela los flujos de trabajo de lista, pero no los de sitio (que existen desde SharePoint 2010)
- Es posible que esta página tarde más de 6 minutos en ejecutar el código. En ese caso deberán modificar el web.config que se encuentra en la carpeta mencionada arriba, específicamente la línea <httpRuntime executionTimeout="360" />
A continuación el código. Espero les resulte útil!
<%@ Assembly Name="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c"%> <%@ Register TagPrefix="spuc" Namespace="Microsoft.SharePoint.WebControls" Assembly="Microsoft.SharePoint, Version=12.0.0.0, Culture=neutral, PublicKeyToken=71e9bce111e9429c" %> <%@ Page Language="C#" MasterPageFile="/_layouts/application.master" Inherits="Microsoft.SharePoint.WebControls.LayoutsPageBase" %> <%@ Import Namespace="Microsoft.SharePoint" %> <%@ Import Namespace="Microsoft.SharePoint.Workflow" %> <%@ Import Namespace="System"%> <%@ Import Namespace="System.Collections.Generic"%> <%@ Import Namespace="System.Text"%> <%@ Import Namespace="System.IO"%> <script runat="server"> protected override void OnLoad(EventArgs e) { FlujosTrabajo.Text = ""; // Salida por pantalla int i = 0; // Cantidad de flujos activos int s = 0; // Cantidad de sitios Error.Text = "Ejecución exitosa"; try { using (SPSite oSite = new SPSite("http://Surpoint")) { foreach (SPWeb oWeb in oSite.AllWebs) // using (SPWeb oWeb = oSite.OpenWeb("/Blog/")) { oWeb.AllowUnsafeUpdates = true; FlujosTrabajo.Text = FlujosTrabajo.Text + "Site: " + oWeb.Url + Environment.NewLine ; s = s +1; foreach (SPList list in oWeb.Lists) { // Verifico si la lista tiene flujos de trabajo SPWorkflowAssociationCollection associationColl = list.WorkflowAssociations; if (associationColl.Count >0) { FlujosTrabajo.Text = FlujosTrabajo.Text + " Lista: " + list.Title + " ("+ (list.Items.Count) +") [Workflows asociados: (" + associationColl.Count + ")]" + Environment.NewLine ; for (int y=list.Items.Count-1; y>=0; y--) { SPListItem oItem = list.Items[y]; // Obtengo los flujos de trabajo activos para el ítem SPWorkflowCollection wfs = oSite.WorkflowManager.GetItemActiveWorkflows(oItem); if (wfs.Count >0) { FlujosTrabajo.Text = FlujosTrabajo.Text + " Ítem: " + oItem.ID + " [WF activos: (" + wfs.Count + ")]" + Environment.NewLine ; for (int x=0; x<wfs.Count; x++) { SPWorkflow workflow = wfs[x]; FlujosTrabajo.Text = FlujosTrabajo.Text + " Workflow cancelado / ítem: " + workflow.ItemId; i = i + 1; // Cancelo el flujo de trabajo SPWorkflowManager.CancelWorkflow(workflow); FlujosTrabajo.Text = FlujosTrabajo.Text + " OK] " + Environment.NewLine ; } } } } } oWeb.AllowUnsafeUpdates = false; oWeb.Dispose(); } FlujosTrabajo.Text = FlujosTrabajo.Text + Environment.NewLine + "*** Total de workflows cancelados: " + i + " ***"; FlujosTrabajo.Text = FlujosTrabajo.Text + Environment.NewLine + "*** Total de sitios : " + s + " ***"; Error.Text = Error.Text + Environment.NewLine + "*** Total de workflows cancelados: " + i + " ***"; } } catch (Exception ex) { Error.Text = "*** Total de workflows cancelados: " + i + " ***"; Error.Text = Error.Text + Environment.NewLine + "Error: " + ex.Message; } } </script> <asp:Content ID="Main" runat="server" contentplaceholderid="PlaceHolderMain" > <asp:TextBox ID="Error" runat="server" Visible="true" TextMode="MultiLine" Rows="3" Width="700px" /> <BR /> <asp:TextBox ID="FlujosTrabajo" runat="server" Visible="true" TextMode="MultiLine" Rows="20" Width="700px" /> </asp:Content>