ipark's blog[MVP SharePoint]

SharePoint related...
随笔 - 23, 评论 - 123, 引用 - 3

导航

关于

My Old Blog: http://freepark.cnblogs.com Email:ipark.cn@gmail.com




Locations of visitors to this page



Creative Commons License

标签

每月存档

最新留言

广告

 

就我的认识,SharePoint Designer的无代码工作流设计器在SharePoint中有两个作用,一个是设计列表的工作流,另一个是给DataForm Web part提供Custom Action(自定义列表操作)的支持(在上一篇文章中我叙述过相关的内容[SharePoint Designer -3]DataForm Web Part中的数据操作)。

不管是哪种使用方法,使用无代码工作流设计器的最终的结果都是:SharePoint会在网站的Workflows文件夹下面创建相应的文件(有XOML文件,工作流配置的XML文件,规则的rules文件,以及很多的asp页面,xoml和xml文件是一定存在的),然后给列表添加一个工作流关联(association)。其中很重要的一个文件是*.wfconfig.xml文件,其形式大致如下:

<WorkflowConfig>
	<Template 
		BaseID="{963BA7F4-2105-4793-85BB-C1D90367D961}" 
		DocLibID="{8a493f4e-22e4-4f34-aefd-55325667ef0f}" 
		XomlHref="Workflows/工作流 1/工作流 1.xoml" 
		XomlVersion="V4.0">
	</Template>
	<Association 
		ListID="{32a8da29-ac60-4e06-86b8-70d4780e563a}" 
		TaskListID="{6822A246-52D5-4BA8-BCBE-826D17620BE7}" 
		StartOnChange="true">
	</Association>
	<ContentTypes>
	</ContentTypes>
	<Initiation URL="Workflows/工作流 1/工作流 1.aspx">
		<Fields />
		<Parameters></Parameters>
	</Initiation>
</WorkflowConfig>

其中DocLibID是Workflows文档库的GUID,ListID是这个工作流绑定到的列表的GUID。

我们可以通过备份还原网站来迁移部署SharePoint Designer设计的工作流。

但是,当我们备份还原网站后,SharePoint Designer设计的工作流在新的网站中不能工作!

问题出在两个地方:

1)新的网站中工作流对应的*.wfconfig.xml中的DocLibID和ListID不能更新到新网站的对应列表的GUID;

2)列表与相应工作流的关联(Association)丢失了。

根据对问题的分析,我们可以找到方法来重建并绑定工作流。

1)首先更新*.wfconfig.xml文件的DocLibID和ListID

2)重新绑定工作流

SharePoint Designer设计的工作流绑定需要利用WebPartPagesWebService的ValidateWorkflowMarkupAndCreateSupportObjectsAssociateWorkflowMarkup方法。

基于以上的分析,我的解决方案是:

1)在Workflows的文件夹下面维护一个Lists.xml文件,形式如下:

<?xml version="1.0" encoding="utf-8" ?>
<Lists>
	<List Name="test" ID="{23d0e43d-b6bf-4670-b69f-871a63f77941}"></List>
	<List Name="custom workflow process" ID="{76ed547a-aa40-4aab-86e2-5e525ea49e1d}"></List>
</Lists>

为什么维护这样一个列表呢?因为网站备份在还原后,列表的名字不会变,但是GUID会变!所以,维护一个存储所有绑定了SharePoint Designer无代码工作流的列表的ID和Name对应关系的XML文件,方便之后更新*.wfconfig.xml文件用。

2)在网站还原以后,通过一下的ReAttachWorkflows方法来更新*.wfconfig.xml文件,并绑定工作流到相应的列表,代码如下:

public static void ReAttachWorkflows(SPWeb objWeb)
{
    string strXOML = string.Empty;
    string strConfig = string.Empty;
    string strRules = string.Empty;
    string strConfigPath = string.Empty;
    string strVersion = string.Empty;
    string strLists = string.Empty;

    SPList objWorkflowList = null;

    try
    {objWorkflowList = objWeb.Lists["Workflows"];}
    catch
    {objWorkflowList = objWeb.Lists["工作流"];}
    System.IO.StreamReader objReader;
    SPFile Filelists = objWorkflowList.RootFolder.Files["Lists.xml"];
    objReader = new System.IO.StreamReader(Filelists.OpenBinaryStream());
    strLists = objReader.ReadToEnd();
    objReader.Dispose();

    System.Xml.XmlDocument xmlLists = new System.Xml.XmlDocument();
    xmlLists.LoadXml(strLists);

    foreach (SPListItem objItem in objWorkflowList.Folders)
    {
	SPFolder objFolder = objItem.Folder;
	foreach (SPFile objFile in objFolder.Files)
	{
	    objFile.CheckOut(false, string.Empty);
	    objReader = new System.IO.StreamReader(objFile.OpenBinaryStream());
	    if (objFile.Name.EndsWith("xoml"))
	    {
		strXOML = objReader.ReadToEnd();
		objReader.Dispose();
	    }
	    if (objFile.Name.EndsWith("rules"))
	    {
		strRules = objReader.ReadToEnd();
		objReader.Dispose();
	    }
	    if (objFile.Name.EndsWith("xml"))
	    {
		strConfig = objReader.ReadToEnd();
		objReader.Dispose();
		strConfigPath = objFile.ServerRelativeUrl.Substring(objFile.ServerRelativeUrl.IndexOf(objWeb.Name) + objWeb.Name.Length + 1);
		System.Xml.XmlDocument xmlConfig = new System.Xml.XmlDocument();
		xmlConfig.LoadXml(strConfig);
		//update GUID of the 'Workflows' document library
		xmlConfig.SelectSingleNode("/WorkflowConfig/Template/@DocLibID").Value = "{" + objWorkflowList.ID.ToString() + "}";
		System.Xml.XmlNode xmlNodeList = xmlConfig.SelectSingleNode("/WorkflowConfig/Association/@ListID");
		System.Xml.XmlNode xmlNodeListOrigin = xmlLists.SelectSingleNode("/Lists/List[@ID='"+xmlNodeList.Value.ToLower()+"']");
		//update GUID of the list to be associated 
		xmlNodeList.Value = "{" + objWeb.Lists[xmlNodeListOrigin.Attributes["Name"].Value].ID.ToString() + "}";
		strConfig = xmlConfig.OuterXml;
		objFile.SaveBinary(System.Text.Encoding.UTF8.GetBytes(strConfig));
	    }
	    objFile.Update();
	    objFile.CheckIn(string.Empty);
	}

	Microsoft.SharePoint.SoapServer.WebPartPagesWebService objWebPartPages = new Microsoft.SharePoint.SoapServer.WebPartPagesWebService(objWeb);
	string strResult;
	strResult = objWebPartPages.ValidateWorkflowMarkupAndCreateSupportObjects(strXOML, strRules, strConfig, "2");

	//associate with list
	string param1 = strConfigPath;
	string param2 = strVersion;
	strResult = objWebPartPages.AssociateWorkflowMarkup(param1, param2);
    }

    xmlLists = null;

}

 

一些想法

1)了解了SharePoint Designer工作流的工作原理了,我们似乎是可以在一定程度上重用一下用SPD设计出来的工作流呢?

思路可以是这样:两个列表必须具有相同的字段(至少是与工作流相关的字段要一样,然后把Workflows文件夹下面的对应的工作流的文件夹复制一个,修改*.wfconfig.xml文件(更新路径,把绑定的列表的GUID更新,然后用ReAttachWorkflows把工作流绑定好。

从原理上来说这样做是行得通的,当然我并没有试过:)

打印 | 张贴于 2008-01-15 22:48:00 | Tag:SharePoint

留言反馈

#re: [SharePoint Designer -4]SharePoint 的无代码工作流在备份还原后不能使用的问题 编辑
Native activities?
2008-04-13 02:58:48 | [匿名:choral]
#回复: [SharePoint Designer -4]SharePoint 的无代码工作流在备份还原后不能使用的问题 编辑
"原生活动岂不更好", 老兄这个是啥意思:)
2008-01-16 10:03:00 | [匿名:ipark]
#回复: [SharePoint Designer -4]SharePoint 的无代码工作流在备份还原后不能使用的问题 编辑
原来是这样关联的啊.
不若扩展一下SPD,让它支持WF的所有原生活动岂不更好?
2008-01-16 10:01:00 | [匿名:笑煞天]
博客主人设置本博客不允许匿名用户发表言论,请登录后再试

Powered by: Joycode.MVC引擎 0.5.2.0