现在的位置: 首页 > 综合 > 正文

用SharePoint Server 2007和Windows Workflow Foundation开发工作流解决方案(二)

2012年12月02日 ⁄ 综合 ⁄ 共 4799字 ⁄ 字号 评论关闭

设置工作流的输出值

 

通过SharePoint对象模型,你可以添加工作流状态到工作流关联列中。每个工作流状态值对于着代表基于零排序列表栏的值中的一个整数。在Microsoft.SharePoint.Workflow.SPWorkflowStatus枚举中前15个值由Windows SharePoint Services预留为内部使用。

 

添加自定义状态值,在Workflow.xml中的ExtendedStatusColumnValues节点下新建StatusColumn元素节点。你可以指定第一个状态值为15,第二个状态值为16,等等。

 

<ExtendedStatusColumnValues>

 <StatusColumnValue>Rejected</StatusColumnValue>

 <StatusColumnValue>Failed Verification</StatusColumnValue>

</ExtendedStatusColumnValues>

 

Windows SharePoint服务预留的最大值是SPWorkflowStatus.Max,因此,你自定义工作流状态时,只需将状态的属性设置为SPWorkflowStatus.Max+1即可。

 

private void setState_MethodInvoking(object sender, EventArgs e)

{

 

    if (!this.changeApproved)

    {

        //Set workflow status to Rejected

        this.workflowState = (int)SPWorkflowStatus.Max;

    }

    else

        //Set workflow status to Failed Verification

        this.workflowState = (int)SPWorkflowStatus.Max + 1;

}

 

启动和恢复工作流

 

将工作流关联到SharePoint列表和文档库中。一个工作流可以:

  • 通过SharePoint用户界面由用户来启动(启动工作流)。如果你使用InfoPath表单,你可以注册一个自定义工作流初始化表单。
  • SharePoint列表和文档库中的列表项创建事件时启动和恢复。
  • SharePoint列表和文档库中的列表项修改事件时启动和恢复。
  • 通过SharePoint对象模型编程启动和恢复。
  • 通过工作流Web服务编程启动。

你需要去了解工作流宿主在每一部分:

  • 最常见的是宿主在W3wp.exe进程,IIS Web应用程序的工作进程是宿主在SharePoint工作流站点上。
  • 当工作流启动时如果你使用DelayActivity或者发生异常,那么宿主进程是Owstimer.exe(Windows SharePoint 计时器服务)
  • 当外部的应用程序(例如:控制台应用程序,Web服务和Windows Communication Foundation服务)通过SharePoint对象模型编程创建项目时,运行代码的进程成为工作流宿主。

特别要考虑宿主进程的工作流实例以外的W3wp.exe工作进程。在关联工作流期间如果你选择On Item Created选项,那么工作流宿主就是通过SharePoint对象模型创建该项目的进程。如果你没有选中On Item Created选项,那么需要你手动启动工作流,或者编程启动工作流。

 

通过SharePoint对象模型创建项目时代码运行在W3wp.exe之外,则工作流启动失败,显示在工作流状态页面上的消息是工作流启动失败(正在重试中)。查看ULS日志显示来自工作流活动代码内部的ArgumentException的下列异常:

 

RunWorkflow: System.ArgumentException: Value does not fall within the

expected range.

at Microsoft.SharePoint.Workflow.SPWorkflowActivationProperties..ctor(

SPWorkflow workflow, Int32 runAsUserId, String associationData,

String initiationData)

at Microsoft.SharePoint.Workflow.SPWinOEWSSService.MakeActivation(

SPWorkflow workflow, SPWorkflowEvent e)

at Microsoft.SharePoint.Workflow.SPWinOeEngine.RunWorkflow(

Guid trackingId, SPWorkflowHostService host, SPWorkflow workflow,

Collection`1 events, TimeSpan timeOut)

at Microsoft.SharePoint.Workflow.SPWorkflowManager.RunWorkflowElev(

SPWorkflow originalWorkflow, SPWorkflow workflow, Collection`1 events,

SPRunWorkflowOptions runOptions)

 

当包含“(正在重试中)”时 Windows SharePoint Services计时器服务工作(计划每五分钟再运行一次)试图启动该工作流。如果你等待五分钟成功启动工作流,那么是发生什么事?

 

SPWorkflowActivationProperties构造器内的代码检测是否以System”的SharePoint帐户启动工作流,在这种情况下System是宿主SharePoint服务器上站点的AppPool账户而不是系统的Windows用户账户。因为如果不是System执行对象模型代码,那么就会抛出空的ArgumentException异常。同时,因为所有Windows SharePoint Services计时服务工作运行在System下面,身份验证通过,进程才能启动。打包创建项目或者通过SPWorkflowManager.StartWorkflow方法内的代码块(SPSecurity.RunWithElevatedPrivileges{delegate()})启动工作流编程时代码不运行,那是因为SPWorkflowActivationProperties类没有提升权限。

 

因此,当你不想或者不能使用工作流宿主的SharePoint站点的AppPool账户时你该如何在SharePoint服务器进程外启动工作流?使用工作流Web服务(_vti_bin/workflow.asmx)启动工作流。

 

工作流Web服务提供高级的功能与Microsoft.SharePoint.Workflow命名空间下的SharePoint对象模型相比较。如果你知道列表项的URL和工作流关联的IDWorkflow.xml文件中定义的)你可以采用工作流Web服务启动工作流。

 

//92EF6E3C-8DC1-41bc-AE1D-C5A04A06E028 is workflow GUID from

//workflow.xml"<Elements>"<Workflow>"[ID].

//The workflow is already associated with the list.

SPWorkflowAssociation associationTemplate =

 list.WorkflowAssociations.GetAssociationByBaseID(new

 Guid("92EF6E3C-8DC1-41bc-AE1D-C5A04A06E028"));

 

WorkflowService.Workflow workflowService =

 new WorkflowService.Workflow();

workflowService.Url =

 "http://developmentserver/sites/workflowtest/_vti_bin/Workflow.asmx";

workflowService.UseDefaultCredentials = true;

workflowService.Credentials =

 System.Net.CredentialCache.DefaultCredentials;

workflowService.PreAuthenticate = true;

XmlDocument workflowParameters = new XmlDocument();

workflowParameters.LoadXml(

 "<workflowData>Any workflow parameters go here</workflowData >");

//listItem is SPListItem object referring on list item in the list.

workflowService.StartWorkflow(

 "http://developmentserver/sites/workflowtest/" + listItem.Url,

 associationTemplate.Id, workflowParameters);

 

工作流启动之后,可以通过On Item Changed 事件或者使用SharePoint对象模型编程来恢复工作流任何主机和进程的帐户(如果该账户有SharePoint数据库和站点的权限)都不会出问题。检查一下只在初始化启动工作流时用到“System”用户,而不是在重新启动工作流时用到它。

 

处理你的工作流配置设置

 

因为很多进程可以作为工作流宿主,如果你的工作流依赖存储在Web.config文件的<appSettings>节点设置的配置文件,那么你必须将这些设置复制到不同位置。其他设置你也可以包含Windows Communication Foundation 配置端点,数据库连接字符串,Web服务的URLsEnterprise Library配置节点。

 

工作流宿主进程

配置文件的名称和位置

SharePoint站点的W3wp.exe进程

SharePoint服务器上的Web应用程序目录的Web.config文件复制到所有前端服务器上

Windows SharePoint Services的计时器服务Owstimer.exe

Owstimer.exeApp.config本地位置在C:"Program Files"Common Files"Microsoft Shared"web server extensions"12"bin"OWSTIMER.exe.config

你的控制台或窗体应用程序

App.config和你执行程序在相同目录下。例如,

配置文件testworkflow.exe是testworkflow.exe.config 。

您的Web或Windows Communication Foundation服务

WebWindows Communication Foundation服务的目录中的Web.config复制到你的服务宿主的所有服务器上

 

通过这些文件复制设置的选择可以存放在众所皆知道的位置(例如你的工作流Feature的文件夹)上单独的.config文件里。这个方法虽然可行,但是这种做法有两大缺点

  • 它要求从外部文件的AppSettings,数据库连接字符串,或者Windows Communication Foundation服务配置节点元素的设置中加载更多的代码。
  • 在前端web服务器上仍然需要复制文件。

 

 

抱歉!评论已关闭.