MOSS工作流开发中,SharePoint Designer 2007可以对MOSS工作流实现无代码的快速开发以及部署,提高工作人员开发工作流的效率和降低工作强度,SharePoint Designer 2007虽然自带了丰富的工作流操作,但是在实际工作中,Designer工作流操作并不能满足我们的全部需求,所以需要开发SharePoint Designer 工作流扩展操作,提高SharePoint Designer 2007 的实用性;由于开发的操作是【工作流Activity库】,可以在任务.net工作流中重复使用,一劳永逸!
 
一.ACTIONS文件格式
SharePoint Designer 在加载服务器工作流条件与操作的时候,都是读取指定路径下的.ACTIONS文件,该文件是一个基于xml格式编写的配置文件,里面记录了对应的操作或条件所对应的程序集,已经程序集中声明的属性,参数类型等信息,MOSS服务器默认有一个WSS.ACTIONS文件,用户可以在该文件中加入<ACTION>节点来定义自己的操作,也可以自己创建.ACTIONS文件,Sharepoint Designer会自动加载该文件夹下的所有.ACTIONS后缀的文件。
 
.ACTIONS文件路径:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\2052\Workflow\
 

1.主要节点概述

节点名称
父节点
含义
<WorkflowInfo>
头节点
<Actions>
<WorkflowInfo>
 
<Action>
<Actions>
定义工作流操作
<RuleDesigner>
<Action>
具体操作中显示的信息,已经参数位置
<FieldBind>
<RuleDesigner>
控制Designer中操作显示的信息,以及参数默认类型默认文本
<Option>
<FieldBind>
可自定义FielBind内的值
<Parameters>
<Action>
定义对应程序集属性的参数集
<Parameter>
<Parameters>
参数与引用程序集对应的信息,如类型、名称等
 

2.节点属性

2.1 <WorkflowInfo>

属性
含义
 

2.2 <Actions>

属性
含义
Sequential
 
Parallel
 
 

2.3 <Action>

属性
含义
Name
操作的名称
ClassName
引用的程序集
Assembly
程序集信息(集名、版本、Culture、公钥)
AppliesTo
 
Category
Designer中的操作选择项中的类表(自定义)
 

2.4 <RuleDesigner>

属性
含义
Sentence
选择操作以后显示的信息,如果句子有参数,在需要加参数的地方插入 [+数字],如:%1
 

2.5 <FieldBind>

属性
含义
Field
参数名称
DesignerType
定义Designer输入参数的方式
Text
默认显示的文本
Id
对应父节点Sentence属性中的参数编号,如:对应父节点的%1 id=”1”
 

2.6 <Parameters>

属性
含义

2.7 <Parameter>

属性
含义
Name
参数名称,必须与引用程序集中声明的属性同名
Type
参数在Designer中的默认值
Direction
定义变量是输出还是输入,值为 ”Out” “In”” Optional”
 

3.节点属性参数取值含义详解

3.1 <WorkflowInfo>

无属性

3.2 <Actions>

Sequential
参数名
含义
 
 
 
Parallel
参数名
含义
 
 
 

3.4 <Action>

节点属性无特殊限制

3.5 <RuleDesigner>

节点属性无特殊限制

3.6 <FieldBind>

 DesignerType
参数名
含义
ParameterNames
 
ChooseListItem
 
ListNames
 
ChooseDoclibItem
 
TextArea
 
FieldName
 
Stringbuilder
 
Operator
 
Integer
 
Dropdown
 
Date
 
Email
 
 

3.7 <Parameters>

无参数

3.8 <Parameter>

Type
         对应.net代码中声明属性的类型
Direction
参数名
含义
In
 
Out
 
Optional
 
 

4.  Actions文件实例

<?xml version="1.0" encoding="utf-8" ?>
<WorkflowInfo>
<Actions Sequential="then" Parallel="and">
    <Action Name="从用户中获取名称"
    ClassName="MyCustomActivity.EventLogger"
    Assembly="MyCustomActivity.EventLogger, Version=1.0.0.0, Culture=neutral, PublicKeyToken=0d31bafc5a063039"
    AppliesTo="all"
    Category="自定义工作流操作">
      <RuleDesigner Sentence=" %1 转化为 %2 ">
        <FieldBind Field="UserName" DesignerType="parameterNames" Text="名称" Id="1" />
     <FieldBind Field="UserLoginName" DesignerType="parameterNames" Text="工程师帐号" Id="2" />
      </RuleDesigner>
    <Parameters>
      <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In"/>
      <Parameter Name="UserName" Type="System.String, mscorlib" Direction="In" />
      <Parameter Name="UserLoginName" Type="System.String, mscorlib" Direction="Out" />
    </Parameters>
    </Action>
</Actions>
</WorkflowInfo>
 

 
 
说明:
以上定义了一个 SharePoint Designer 2007 工作流操作。该操作引用程序集的 MyCustomActivity.EventLogger
操作名称:从用户中获取名称(图1
SharePoint Desiner 2007 工作流操作扩展_计算机(图1
组:自定义工作流操作(图2
SharePoint Desiner 2007 工作流操作扩展_Office_02(图2
操作详细设置设两个参数(图3),都为工作流变量类型(图4),点击新建变量 默认类型为 字符串(图5
SharePoint Desiner 2007 工作流操作扩展_Office_03(图3
SharePoint Desiner 2007 工作流操作扩展_Office_04(图4
SharePoint Desiner 2007 工作流操作扩展_Office_05(图5
Parameters节点内的信息是与.net代码内声明的属性对应应的参数,要求必须名称和类型都与代码中的属性保持一致
二.用Microsoft Visual Studio 2005开发 SharePoint Designer 2007 工作流扩展操作
系统需求:
Microsoft Visual Studio 2005
.NET Framework 2.0
.NET Framework 3.0
Windows WorkFlow Fundation
 

1.    工作流项目模板

安装好所需的软件后,打开Microsoft Visual Studio 2005,文件 -> 新建 -> 项目,展开你所需要的语言,选择 Workfow( 该选项要在安装Windows WorkFlow Fundation基础上才会出现 )
SharePoint Desiner 2007 工作流操作扩展_Office_06
微软提供多个工作流模板,这里由于我们要开发的是一个Designer的扩展操作,所以选择 【工作流 Activity 库】,新建一个项目
创建项目后可以看到【工具箱】中多了【Windows workflow】,这是微软提供的一组可视化工作流设计空间,当前实验并未涉及到这些控件的使用,使用不做介绍。
SharePoint Desiner 2007 工作流操作扩展_Microsoft_07

2.    开发实例

以下使用一个简单的实例,说明整个开发的方法
功能:由用户的姓名
在解决方案中,选择Activty1.cs文件,右键-【查看代码】,我们需要实现功能的代码还有属性的声明,都将写在Activty1.cs文件内
SharePoint Desiner 2007 工作流操作扩展_MOSS_08
首先声明一个变量LoginName 用于获取用户的帐号,声明代码:
public static DependencyProperty LoginNameProperty =
           System.Workflow.ComponentModel.DependencyProperty.Register("LoginName",typeof(string),typeof(Activty1));
[Category("自定义工作流操作"), Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string LoginName{
     get{
           return ((string)(base.GetValue(LoginNameProperty)));
        }
     set{
           base.SetValue(LoginNameProperty, value);
        }
}
 
再声明一个变量Name 来得到用户的姓名,声明代码
public static DependencyProperty NameProperty =
            System.Workflow.ComponentModel.DependencyProperty.Register("Name", typeof(string), typeof(Activty1));
[Category("自定义工作流操作"), Browsable(true)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public string Name{
     get{
           return ((string)(base.GetValue(NameProperty)));
        }
     set{
           base.SetValue(NameProperty, value);
        }
}
说明:
在实例化DependencyProperty变量时候必须注意,
参数格式为:
DependencyProperty.Register(参数1:所声明属性的名称,参数2typeof(声明属性的类型),参数3typeof(所在类的名称))
 
由于需要获取的是MOSS中的信息,所以还需要一个参数,但是这个参数不会显示到Designer的操作界面上
public static DependencyProperty __ContextProperty =
DependencyProperty.Register("__Context", typeof(WorkflowContext), typeof(EventLogger));
[ValidationOption(ValidationOption.Required)]
[DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
public WorkflowContext __Context{
    get{
          return (WorkflowContext)base.GetValue(__ContextProperty);
       }
    set{
         base.SetValue(__ContextProperty, value);
       }
}
使用这个属性,获取当前MOSS站点的信息,包括我们所需要获取的用户帐号以及姓名,由于需要使用到Microsoft.SharePoint.WorkflowActions. WorkflowContext类,但是默认情况该平台内未注册Microsoft.SharePoint.WorkflowActions名称空间,所以必须从MOSS服务器下找到该类,注册到我们的当前系统中。
一般情况下,这个DLLMOSS服务器以下路径找到:
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\ISAPI
找到后直接使用 【所有程序】-【Microsoft Visual Studio 2005】-【Visual Studio Tools】-【Visual Studio 2005 命令提示】
输入以下命令,将DLL注册到GAC
gacutil /i DLL在本机的路径
然后应用该重启Microsoft Visual Studio 2005,添加应用该程序集合
 
接下来我们重载Execute()方法,完成我们需要的操作,具体的代码如下:
protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext){
     try{
        // 定义 SPUserCollection __Context 中获取MOSS站点所有用户信息
        SPUserCollection spUserCollection = __Context.Web.AllUsers;
        // 定义 foreach 循环
        foreach (SPUser spUser in spUserCollection){
             // 判断对比用户的登录帐号
             if (spUser.LoginName == LoginName){
                // 将用户的姓名存储到 NameProperty 属性中
                base.SetValue(NameProperty, spUser.Name);
                break;
               }
           }
        }
        catch(){}
return ActivityExecutionStatus.Closed;
}
通过比对用户帐号,从网站的用户信息中搜索到用户的名称,并获取匹配用户的姓名
代码开发工作到此就算完成了,由于我们的DLL最后是要部署到MOSS服务器上的GAC中,所有必须给它加上强签名:
选中解决方案中的项目 【右键】-【属性】
在属性页面中选择【签名】-【为程序集签名】
SharePoint Desiner 2007 工作流操作扩展_计算机_09
在下拉框中选择【<新建>】,给签名文件添加名称,密码可以不用输入
最后还必须注意一点的是,VS开发的解决方案内的项目默认的程序集名称都是项目名称
SharePoint Desiner 2007 工作流操作扩展_sharepoint_10
程序集名称必须改为:命名空间 + 项目名称,否则Designer无法加载到该程序集
最后生成项目,这样就得到我们需要的DLL
 

3.    部署

程序开发好后,剩下的就是部署到MOSS服务器上,首先,先获取我们开发的DLLPublicKeyToken,方法如下
【所有程序】-【Microsoft Visual Studio 2005】-【Visual Studio Tools】-【Visual Studio 2005 命令提示】
sn  –T  DLL路径
记录下PublicKeyToken后,将DLL部署到GAC
gacutil  /i  DLL路径
这样,我们开发的DLL已经注册到MOSS服务器上的程序集中了,可以将它加到MOSS中了
由于Designer中的工作流操作以及条件全部都是从MOSS服务器上获取去的,接下来就是配置一下.ACTIONS文件,把我们自定义的操作加到Designer中,打开以下路径
C:\Program Files\Common Files\Microsoft Shared\web server extensions\12\TEMPLATE\2052\Workflow\
可以看到文件下有一个WSS.ACTIONS文件,这个文件是XML格式编写的,所有可以直接用记事本打开,里面是MOSS自带的工作流条件和操作,我们可以直接在该文件下配置我们的操作,但是不推荐这样做,不利与区分,且维护起来十分麻烦。在该文件下新建一个.ACTIONS文件,名字可以随意,Designer都可以识别到该文件夹下.ACTIONS后缀的文件
配置文件编写如下:
<?xml version="1.0" encoding="utf-8" ?>
<WorkflowInfo>
<Actions Sequential="then" Parallel="and">
    <Action Name="从用户帐号获取用户名字"
    ClassName="ActivityLibrary1.ActivityLibrary1"
    Assembly="ActivityLibrary1.ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken=DLLPublicKeyToken "
    AppliesTo="all"
    Category="自定义工作流操作">
      <RuleDesigner Sentence=" %1 获取 %2 ">
        <FieldBind Field="LoginName" DesignerType=" SinglePerson" Text="帐号" Id="1" />
        <FieldBind Field="Name" DesignerType="parameterNames" Text="名字" Id="2" />
      </RuleDesigner>
    <Parameters>
      <Parameter Name="__Context" Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" Direction="In"/>
      <Parameter Name="LoginName" Type="System.String, mscorlib" Direction="In" />
      <Parameter Name="Name" Type="System.String, mscorlib" Direction="Out" />
    </Parameters>
    </Action>
</Actions>
</WorkflowInfo>
需注意的是在Parameter节点中,Type的值,逗号必须紧跟类型后面,如Type="System.String, mscorlib",如果Type="System.String , mscorlib"中间出现空格,Designer将无法识别该默认类型,这个错误比较不容易发现。
这样Designer已经可以识别到我们的所定义的操作了,最后还需要在我们所要使用的MOSS站点中web.CONFIG中添加相应的节点
<authorizedTypes>中,添加
<authorizedType Assembly=" ActivityLibrary1.ActivityLibrary1, Version=1.0.0.0, Culture=neutral, PublicKeyToken= DLLPublicKeyToken " Namespace=" ActivityLibrary1" TypeName="*" Authorized="True" />
OK,重启一下IIS
【开始】-【运行】,输入CMD,键入以下命令
Iisreset /noforce
部署完成,可以designer中打开这个站点,试验一下自己定义的操作了