SharePoint多级审批工作流开发文档[Sequential版] v1.1

研究了一段时间SharePoint工作流之后的一个总结.
基于ECM Starter Kit Beta2 开发.
工作流程图如下:

点击下载项目源码+开发过程文档

请大家多多指教.

注:本文为初学MOSS工作流时所写,本文所开发的工作流可以有更好的方式.

最后更新于2007年8月5日更新部分代码,修正某些情况下任务的分配对象会丢失地问题.

91 Comments

  1. yang 说道:

    怎么解压出错啊

  2. 笑煞天 说道:

    可能下载不完整吧.

  3. yang 说道:

    哦,好了.我研究研究,正苦于没有学习资料呢

  4. GSpring 说道:

    佩服,文档很完整。
    我正在找这方面的资料,多谢了!

  5. yang 说道:

    对项目调试的时候,附加到workflow进程,为什么有时调试不了,输出未加载符号之类的.

  6. lwgmxl 说道:

    你好,我在配<Association_FormURN>associationFormURN</Association_FormURN>
    <Instantiation_FormURN>instantiationFormURN</Instantiation_FormURN>的这个是两个不同的Infopath表单,,发布的sharapoint成功后,,在工作流启动的页就说找不到Instantiation_FormURN这个表单,,为什么会这样呀???

  7. 笑煞天 说道:

    你的Association form中有没有Contact Selector控件,如果有多个的话,可能会��这样的错.

  8. 笑煞天 说道:

    To yang:
    是附加到w3wp.exe吗?在附加进程对话框中的“附加到”选择workflow代码。

  9. yang 说道:

    to 笑煞天:
    是附加到w3wp.exe,且是workflow类型的那个.也选择了workflow代码.新手上路,很多东西不是很清楚.柴兄的文档挺详细的,不错的学习资料.

  10. 笑煞天 说道:

    to yang:
    还没有遇到你说��这种情况,不太清楚…
    我也是新��啊.

  11. lwgmxl 说道:

    笑煞天兄,,问你个问题,如果我的工作流Infopath 表单一定需要写C#.NET代码的,,那我这个工作流应该怎么样发布到sharepoint???
    好象那个写了代码的InfoPath的表单发布不成功!

  12. 笑煞天 说道:

    to lwgmxl:
    请参考OTEC中的��篇文章,或许有帮助:
    http://www.msotec.net/Forums/ShowThread.aspx?PostID=7044

  13. syntax 说道:

    我在用 xsd的时候 报错 :不支持 URI格式
    咋回事阿

  14. 笑煞天 说道:

    to syntax:
    你确定你填写的uri格式正确吗?表单的uri地址可以在infopath中复制,文档中写了这点.

  15. NGZ 说道:

    正在学习老师的例子,一些不明之处望指教:一些类的详��说明不知从哪里获得,如“task0_Properties.AssignedTo”我在WSS3sdk中查了一下,在SPWorkflowTaskProperties Class只找到个“语法”说明,关于用途(或作用)方面的说明在哪?还有VS中Windows Workflow工具箱中的活动的说明又在哪里查呢?
    谢谢!

  16. leo_yo 说道:

    你好,我按你的那个例子做了后,怎么在第一步开始审批时就不行了,就是出现那个InitForm后我点击“启动工作流”,但是页面就是不跳转,好像没有提交一样,不知道是哪出了问题?新手上路

  17. 笑煞天 说道:

    有没有给按钮添加"提交"操作呢?

  18. leo_yo 说道:

    有呀,添加完了。我也参考了msdn上提供的那个workflow的开发过程了,过程应该没错,会不会是moss中有什么设置的问题呢?

  19. 笑煞天 说道:

    msdn上的教程并不详细.
    提交操作设置正确了吗?提交到宿主环境.

  20. 我啊 说道:

    我正在找这方面的资料,多谢了!

  21. everx 说道:

    如果我用的是WSS3.0的话,是没有microsoft.office.workflow.tasks.dll这个程序集的,也就是无法在代码中获得contact selector控件的数据,请问WSS3.0 中有没有替代的方法,谢谢啦!

  22. Steven 说道:

    强!佩服!

  23. sinmen 说道:

    柴兄,帮忙啊。我在工作留流中写到 private void createTask1_MethodInvoking(object sender, EventArgs e) { tracerInfo = department + taskOriginator + "申请借支,金额为" + money + "元。/n" + "借支用途:" + remark; taskId1 = Guid.NewGuid(); taskProperties1.TaskType = 1; taskProperties1.ExtendedProperties["Content"] = tracerInfo; }但在表单中显示不出来,痛苦ing。。

  24. 笑煞天 说道:

    你的infopath表单中文本框的域是Content吗?辅助数据源(XML)中有没有对应的ows_Content?

  25. sinmen 说道:

    @笑煞天有啊,域是Content,辅助数据源(XML)中也有对应的ows_Content。请问还可能是什么原因引起的?我发了代码你,可以帮忙看看吗。谢谢了

  26. 笑煞天 说道:

    @sinmen
    在infopath中做绑定了吗?
    不好意思,最近比较忙,抽不出时间看你的代码了.
    其实是,我最近已经转向ajax了.

  27. 刘BEIBEI 说道:

    哥哥你好.我想请问一下我部署已经成功了,如何才能启动工作流呢?
    我在主页上看我到我发布的那个.能指点我一下吗.谢谢拉

  28. 刘BEIBEI 说道:

    写错了是在主页上看不到我部署的,所以我不知道如何才能让INFOPATH那个表单运转起来.麻烦指点一下.万分感谢拉

  29. 笑煞天 说道:

    进入文档库,添加你部署的工作流,然后上传一个文档,在其操作菜单中选择工作流。

  30. Armslave 说道:

    如何更改文档的审批状态,

  31. 笑煞天 说道:

    @Armslave ,
    本例中,指定的审批者会在自己的任务列表中看到审批任务,在任务中可以通过勾选/不勾选"通过审批"复选框来更改审批状态.

  32. Armslave 说道:

    是这样,我是想当流程走完后是批准了还是拒绝了,在文档库中该文档的审批状态一栏可以看到显示,我在运行该例子时,流程各级都走完了,但是文档库中,只显示工作流已完成,审批状态却没有更新,不知道是怎么回事

  33. 笑煞天 说道:

    @Armslave ,
    误会了你的意思,这个问题应该是因为我的代码中并没有操作"审批状态"这一栏的原因.
    应该可以在代码中修改这一栏,抱歉我现在没法尝试,你可以试试.

  34. Jimmy 说道:

    感謝老師給出如此精典的例子﹐這對我們初學者真是幫助不少。我也有試著做一個自���的工作流.在實踐的過程中﹐出現以下錯誤﹐望老師出面給看看.感激!
    載入infopath表單時出現下面提示:

    載入表單時發生錯誤.
    無法開啟此表單,此表單未啟用工作流程。

    起初懷疑是任務的TaskType沒有設定(在workflow.xml中有配置表單的FormURN),所以遭成此原因,可是在檢查之后,卻沒有發現問題.所以我想知道以下問題的答案:
    1.workflow中設定的表單(通過設定表單的FormURN實��),如何與代碼實現聯系起來,(即workflow.cs中如何讓sharepoint server打開我指定的infopath表單,是通過設定任務的TaskType嗎?TaskType=0就表示啟動workflow.xml中的<Task0_FormURN>表單唯一表識</Task0_FormURN這個表單,依次類推.)
    2.如果1正確,那么在一個ifelseActivity中的兩個表單中的TaskType要如何設定呢,是設定為一樣呢﹐還是得有先后順序.就像老師例子中講到的ifelseactivity節一樣.
    望回答,謝謝!

  35. Jimmy 说道:

    @syntax
    這應該是你命令格式問題,注意命令間的空格,

  36. Jimmy 说道:

    @lwgmxl
    你可以看看這個目錄下是否有你設計好的表單模板
    C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\FEATURES\ProjectName\
    如果有應該是你表單FormURN的錯誤,再或者你可以查看sherepoint server的log,路徑如下:C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\LOGS﹐或許也可以找到答案.
    如果沒有那証明你的workflow發布是失敗的,重新發布一次,看看命令窗口有提示什么錯誤沒有,如果順利的話,應該出現四個"作業已成功完成"的提示.

  37. Jimmy 说道:

    @yang
    你好,這種情況在我實做的時候,也遇到過,你即便是設置了再多的中斷點,VS2005仍然Debug不到,這不是VS的問題,也還同樣是workflow發布不成功遭成的,請仔細檢查workflow發布時有沒有給出錯誤提示,比如"找不到路徑","找不到文件"什么的.一旦你發布成功,相信就可以解決你的問題.

  38. 笑煞天 说道:

    @Jimmy
    老师不敢当,不必客气。
    在workflow.xml中执行的许多FormURN可以看作一个表单数组,在后台代码中如果想指定需要显示得的表单,可以通过设置该任务得TaskType来实现,TaskType=0可以看作FormURN[0],这样是否更好理解。
    在IfElse中的两个表单得TaskType得设定取决于你得业务需要,本例的做法仅供一种参考而已。

  39. Jimmy 说道:

    謝謝您回���,今天上午的問題已經解決,原來是在設計InfoPath表單時忘記了將安全性與信任設為"完全信任"導致!很高興的告訴你,自己的一個WorkFlow開發的任務也快完成了,這要多多感謝你的這篇文章.TKs

  40. 笑煞天 说道:

    @Jimmy
    恭喜你,共同学习,共同进步!

  41. Armslave 说道:

    我自己参考这个做了个流程,借用了函数
    private string GetNextAssigneeDisplayname(string assigneeXml)
    {
    Microsoft.Office.Workflow.Utility.Contact[] contacts = Microsoft.Office.Workflow.Utility.Contact.ToContacts(assigneeXml, workflowProperties.Web);
    if (contacts[0] != null)
    return contacts[0].DisplayName;
    else
    return "";
    }
    在调用时
    Task1_TaskProperties1.AssignedTo = GetNextAssigneeDisplayname(Task1_TaskProperties1.ExtendedProperties["contact"].ToString());
    总是提示,未将对象引用至实例是怎么回事~!是不是contact selector 还有什么设置没做

  42. 笑煞天 说道:

    @Armslave,
    是否正确设置Contact Selector控件的域组?
    以及CONTEXT辅助数据源?

  43. Armslave 说道:

    都是按照教程设置的,可是调试时发现,Task1_TaskProperties1.ExtendedProperties["contact"].ToString()总是null,您估计是什么地方出现了问题

  44. 笑煞天 说道:

    @Armslave,
    仔细检查Task1的Infopath表单,应该是问题所在.
    比如域,数据源(主与辅助),以及二者的对应关系.

  45. 朵朵[未���册用户] 说道:

    问个题外话:您的工作流程图是用什么工具画的呀?

  46. 笑煞天 说道:

    @朵朵
    工具很简单,Word 2007.

  47. testasd 说道:

    是不是每个审批流程都要用一个WHILIE?
    然后我按你的方法模拟了一个流程,我点击启动工作流,页面刷新下就没反应,不会跳转,能否说下什么原因,我设置了.NET宿主提交验证

  48. 笑煞天 说道:

    @testasd
    不是每个流程都需要While的,采用什么样的活动取决于你的流程所需.
    无法启动工作流有很多原因,你可以查看log查找原因.

  49. liangzhu 说道:

    刚开始做WORKFLOW,您的例子非常好,我试着做了一下,有一个问题盼望您能给予帮助:
    我安装的是MOSS 2007+VS 2008
    您的例子中INFOPATH 表单里面提交动作是提交到宿主环境中,这样它是否就不会保存到某个DOCUEMENT LIBRARY中呢?它会存在于什么地方?我按照您的程序调试:表单‘提交’按钮按了之后表单关闭(因为有关闭表单动作),但是不能保存到SHAREPOINT,也不能触发工作流。
    我试着把提交的数据链接改为链接到某个DOC LIBRARY,这样就能保存到SHAREPOINT服务器���了,然后手动启动工作流是可行的。
    所以我想请问是否我遗漏了某些设置,导致提交后无法启动工作流?

  50. zaq02 说道:

    最近也在研究MOSS2007,系统中有一个自带的Approval工作流模版,可以用于收集反馈。而我自己也在用VS2005,Infopath2005设计工作流并部署到MOSS站点。可问题是我使用ActiveX的Contact Selector控件总是无法将选择的所有参数(用户)传递过去,每次只能传递一个用户的ID并分配该任务。

    task_property.AssignedTo=….Contact[0].DisplayName

    ��知道怎样同时将Contact[0] Contact[1] …..多个在Contact Selector控件中选择的用户都分配同一任务
    想做一个和Approval模板中同时选择多个用户(在同一个Contact Selector控件中)并将同一任务分配给选择的所有用户的工作流。

    自己写代码找不到相应的函数,想参考Approval又找不到该摸板的原代��

  51. testasd 说道:

    你好,我按你的那个例子做了后,怎么在第一步开始审批时就不行了,就是出现那个InitForm后我点击“启动工作流”,但是页面就是不跳转,好像没有提交一样,不知道是哪出了问题?新手上路

  52. 笑煞天 说道:

    @zaq02
    可以试试在ReplicatorActivity中CreateTask,ReplicatorActivity会根据你设置的条件循环执行.
    关于ReplicatorActivity的内容请参考:http://www.cnblogs.com/xiaoshatian/archive/2007/07/27/833001.html

  53. 笑煞天 说道:

    @liangzhu
    @testasd
    请仔细浏览文档,一句话都不可遗漏哦.呵呵.

  54. 急需 说道:

    樓主好。

    我按照您的文檔一步一步地做,最後也部署成功,出現四個“作業完成成功”

    可是,在MOSS的網站啟動工作流時,卻找不到剛才部署的工作流。

    還望您指點,謝謝。

  55. 笑煞天 说道:

    @急需
    如果点击启动找不到工作流的话,那么工作流是如何关联的呢?有些奇怪哦。
    你可以到经典的12目录查看log文件。

  56. songcan 说道:

    楼主真是太伟大了!多谢无私分享,希望有问题能得到您的指点,谢谢!

  57. sldjflsdjf 说道:

    能否实现在表单库里直接审批,而不是在任务里审批

  58. sldjflsdjf 说道:

    我想要一个这样的流程,请教大致的思路。做一个审批流程,是在直接在新建的表单库里审批,申请者打开此表单库,点击新建,打开表单,填写信息,点击确定,传给第一个审批者;审批者进入此表单库,在表单库里,直接打开刚才要审批的表单,此时表单的样式是审批者的样式,填好审批意见,点确定,传给第二个审批者,直到传递结束。就是说一切审批工作都是直接打开表单进行操作,而不是在任务列表里,请问如何实现?

  59. @sldjflsdjf
    我的大概想法是,在工作流���不适用任何任务活动,每次都更新表单域值和表单修改权限。

  60. chenql 说道:

    非常好的资料,2007-2008都有人顶,做的很细,感谢。
    不过用搜索关键字Moss,InfoPath很难找到这篇文章.

  61. virus 说道:

    correlationToken是必须设置项吗
    onWorkflowActivated活动的属性一般需要设置吗,默认可以吗,大概什么时候需要设置呢

  62. virus 说道:

    和工作流的交互,使用callexternalmethod和handleexternalevent,前者用来工作流给Host发消息,后者用来Host给工作流发送消息
    如果我想随时给工作流发送消息呢,给正在运行的工作流呢,好像就是handleexternalevent,不是使用sharepoint预定义的任务工作流,使用我们自定义的交互服务接口

  63. virus 说道:

    工作流运行到一个节点的时候,要等待事件的发生,就会序列化并且持久化到数据库,这时候工作流就会睡觉。
    被持久化的工作流不再内存中存��。
    当工作流等待的事件发生之后,工作流被反持久化、发序列化并且激活,从上回睡觉的地方开始继续。
    在这个过程中,序列化和持久化是自动的吗,是不是在添加sql持久化服务之后就可以自动呢,使用预定义的任务工作流事件这些可以自动吗?还是说都需要手动指定呢。

  64. @virus
    #61 correlationToken是必须的,没有它的话工作流就不知道哪些活动之间是有关联的。

    #62 理论上使用HandleExternalEvent活动是可以接收到宿主触发的事件,但是,现在宿主是SharePoint,你得确定你有办法在SharePoint中触���工作流的事件才行。

    #63 在SharePoint中,SharePoint已经内置了持久化服务,不需要你指定。

  65. virus 说道:

    1、correlationToken是设置活动的关系的,表明他们是一家的,是处理一个任务的
    2、那我想在工作流运行的过程中操作工作流呢,而不是单纯的在任务修改的过程中,是不是没有这样的需要呢,如何处理呢
    3、不需要指定是说数据库都定义好了,方法还是需要调用的吧,难道使用预定义的事件,比如说OnTaskChanged这类东西,就自动持久化吗(在我添加了持久化服务之后),不用自己写代码指定了吧
    希望可以和你在MSN中交流
    谢谢

  66. @virus
    1.理解正确。
    2.SharePoint提供了修改工作流的机制,通过ModifyWorkflow和OnWorkflowModified活动来实现。
    3.使用预定义的活动当然不需要你调用了,钝化是自动完成的。

  67. virus 说道:

    在xml文件中为什么右键的插入代码中没有sharepoint server

    我已经把它的schemas设置为sharepoint的wss.xsd文件了

  68. ddddddd 说道:

    wss 3.0能不能用呀,不用moss 2007

  69. chen hui 说道:

    刚开始做WORKFLOW,您的例子非常好,我试着也照做了一个,有一个问题盼望您能给予帮助:
    我安��的是MOSS 2007+VS 2008
    表单都是按照你的步骤做的,没更改程序。
    我按照您的程序做发布,在sharepoint可以找到工作流,创建工作流。在新建文档后,选择此工作流,可以出来第一个表单。

    表单‘启动工作流’按钮按了之后没反应,不能触发工作流, 不知道怎么回事,
    是不是我什么地方没设置好呢

  70. @chen hui
    忘记“启动工作流”按钮添加提交规则了吧?

  71. chen hui 说道:

    谢谢楼主!我今天重新做了一下���单。调试的时候代码运行到
    XmlTextReader xtr = new XmlTextReader(new System.IO.StringReader(workflowProperties.InitiationData));
    提示出这样的错误:
    用户代码未处理 ArgumentNullException
    值不能为空
    参数名:s

  72. chen hui[未注册用��] 说道:

    这样的是不是INIT.CS生成出错了 怎么弄呢

  73. chen hui 说道:

    谢谢楼主 搞明白了 更改了新表单后没更新feature的缘故,现在在表单‘启动工作流’按钮按了之后是可以触发启动工作流的页面,但在启动工作流页面执行几秒钟后,自动返回文档库页面,状态显示为‘进行中’,点击’工作流任务’后,却发现我建立的工作流状态为‘未启动’,这个是怎么回事呢,是不是又是表单的问题呢~

  74. @chen hui
    任务还没有开始编辑,当然是未启动了。

  75. chen hui 说道:

    调试的时候,createTask1_MethodInvoking执行通过了,过了这个方法以后就直接自动返回文档库页面,有时候是一直执行‘操作正在进行’….这个问题改怎么弄呢��老大,救命啦~

  76. @chen hui
    其实并没有任何问题,这个工作流的功能是:为审批人创建审批任务,等审批人完成了任务,工作流就会继续处理,createTask1_MethodInvoking执行过后,任务就创建好了,所以,就让审批人用鼠标将箭头光标移动到任务列表中分配给审批人的任务上,轻轻的点击左键,等到任务打开后,填入一些信息,选择通过或者拒绝,如果选择通过的话,别忘记选择下一级审批者,然后点击确定,工作流就可以继续了。
    明白?
    关于一直是“操作正在进行”的问题,这确实是个问题,就当作SharePoint在摆架子吧。

  77. chen hui 说道:

    谢谢楼主 这么耐心的给我这个门外汉讲解。还有些地方不明白。就是启动工作流以后,所在文档库显示‘进行中’,但我照你的步骤,我换了审批用户进来,审批人用鼠标将箭头光标移动到任务列表中分配给审批人的任务上,轻轻的点击左键,等到任务打开后,发现不是我做的Task1表单,而是项目信息页面,里面显示些比如标题、优先级、状态、分配对象等信息,如果我点‘编辑项目’,输入信息,确定。然后又回到任务列表,我想这样的话和我定制的工作流好象没什么关系了。有些想不通,是不是我做的task1表单出问题了呢?弄的调不出来~

  78. @chen hui
    如果你点击任务却没有显示InfoPath任务表单的话,请检查:
    1.Workflow.xml文件中是否添加了任务的FormURN。
    2.代码中是否将该任务的TaskType指定为相应的FormURN序号。

  79. chen hui 说道:

    谢谢 看到你的回复太开心了 实在是想破头也不知道问题在那
    我查了一下:
    1、workflow.xml文件已配置好,如下:
    <Task0_FormURN>urn:schemas-microsoft-com:office:infopath:Task0:-myXSD-2009-01-17T06-21-05</Task0_FormURN>
    <Task1_FormURN>urn:schemas-microsoft-com:office:infopath:Task1:-myXSD-2009-01-17T01-52-23</Task1_FormURN>
    <Task2_FormURN>urn:schemas-microsoft-com:office:infopath:Task2:-myXSD-2009-01-17T05-06-27</Task2_FormURN>
    <Task3_FormURN>urn:schemas-microsoft-com:office:infopath:Task3:-myXSD-2009-01-17T06-05-39</Task3_FormURN>
    FormURN里面的值是我从发布前表单属性里面取得的。

    2、在createTask1_MethodInvoking方法里有
    task1_Properties.TaskType = 1;
    代码,会不会是其他的问题呢。这几天真想破头了。呵呵

  80. @chen hui
    点击“编辑项目”也不会显示InfoPath任务表单?

  81. chen hui 说道:

    是的 多谢 笑兄了 找到问题了
    TaskListContentTypeId没给设置~~
    不过好象直到最后一个审批完以后 任务就消失了 如果能提示 或者回到第一个提交任务人的手里 这样就完整��点了。

    弄了好几天 我还真菜 呵呵

  82. @chen hui
    哦,你使用Visual Studio 2008吧?Visual Studio 2008中提供的Workflow.xml默认是没有这个属性。
    任务消失��因为我使用了DeleteTask活动,这个是由你来选择的。

  83. @chen hui
    哦,你使用Visual Studio 2008吧?Visual Studio 2008中提供的Workflow.xml默认是没有这个属性。
    任务消失是因为我使用了DeleteTask活动,这个是由你来选择的。

  84. student090212 说道:

    你好,按照您的例子我做了一遍,在激活feature时,提示“值不在预期范围内”,请问这是怎么回事!谢谢!

  85. saberFan 说道:

    我很认真的按照文档一步一步完成后,最后部署过程也没有提示问题,但是在启动工作流的时候跳转到Init.xsn表单后,点击启动工作流不跳转
    发现之前也有人问过同样的问题。。。
    但是按钮上的规则绝对没有忘记添加,而且发现工作流实例也的确不曾真正创建��在OnWorkflowActivate中设置的断点也不曾被运行到
    希望笑煞天能给予一些能够用来查错的方法

  86. @saberFan如果你确信你的按钮添加了正确的规则的话,那么只能采用终极方法了:查log文件。

  87. bibing 说道:

    请问下这个workflow项目怎么调试呢?具体些,我是个菜鸟

  88. Windie Chai 说道:

    @bibing在Visual Studio 2008里,猛击F5开始调试。

  89. [...] 之后我在《SharePoint多级审批工作流开发文档[Sequential版]》这篇文档中详细的描述了整个开发过程并提供了项目源码下载。 [...]

  90. [...] 去年我发布过一个MOSS多级审批工作流,采用顺序工作流模式开发;后来又做了一些改进,用ConditionedActivityGroupActivity取代了繁复的WhileActivity+IfElseActivity嵌套,但仍然是顺序工作流。 [...]

Leave a Reply