jilh 发表于 2015-9-26 07:58:46

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

设置工作流的输出值
  
  通过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>".
  //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服务器上仍然需要复制文件。
  
  
页: [1]
查看完整版本: 用SharePoint Server 2007和Windows Workflow Foundation开发工作流解决方案(二)