|
设置工作流的输出值
通过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和工作流关联的ID(Workflow.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服务的URLs,Enterprise Library配置节点。
工作流宿主进程
| 配置文件的名称和位置
| SharePoint站点的W3wp.exe进程
| 将SharePoint服务器上的Web应用程序目录的Web.config文件复制到所有前端服务器上
| Windows SharePoint Services的计时器服务(Owstimer.exe)
| Owstimer.exe的App.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服务
| 在Web或Windows Communication Foundation服务的目录中的Web.config复制到你的服务宿主的所有服务器上
|
通过这些文件复制设置的选择可以存放在众所皆知道的位置(例如你的工作流Feature的文件夹)上单独的.config文件里。这个方法虽然可行,但是这种做法有两大缺点:
- 它要求从外部文件的AppSettings,数据库连接字符串,或者Windows Communication Foundation服务配置节点元素的设置中加载更多的代码。
- 在前端web服务器上仍然需要复制文件。
|
|