65.9K
CodeProject 正在变化。 阅读更多。
Home

工作流:将文件从一个站点复制到另一个服务器或站点

starIconstarIconstarIconstarIconstarIcon

5.00/5 (1投票)

2012年6月22日

CPOL

3分钟阅读

viewsIcon

38517

此工作流将把一个站点文档库中的文件复制到另一个服务器或 Web 应用程序。

免责声明

我不是一个经过正规培训的程序员。我正在上谷歌的计算机科学学院。请尽量不要嘲笑我的代码。对于因查看我的代码而引起的任何医疗问题,我不承担任何责任。

引言

本文提供的代码可用于创建一个自定义工作流操作,该操作会将一个文档从一个站点的文档库复制到另一个站点的库。在 SPD 中添加操作时,用户将能够提供目标网站 URL 和目标库。

此操作不会将文档元数据复制到目标站点。它只会复制项目。此操作不会将作者姓名复制到目标站点。它只会复制项目。此操作不会将项目版本号复制到目标站点。它只会复制项目。

背景

在互联网上搜索了一个现成的代码示例后,我不得不自己解决这个问题。因为我不是程序员,所以花了一段时间才把它拼凑起来。希望它能帮助像我这样需要一个好的入门程序来开始的人。

此代码已在我的开发环境和 SharePoint 2010 Enterprise 的小型安装上进行了测试。

使用代码

我不会详细介绍如何创建自定义工作流操作项目。有很多关于如何执行此操作的好文章。我在下面提供了一些参考。设置项目后,根据需要替换下面的代码。对于像我这样的新手,这意味着

  1. 确保此处列出的 usings 在您的项目中
  2. 替换命名空间声明后花括号内的代码
  3. 务必在 windows 程序集中注册您的项目,并将此处列出的公共令牌替换为您的公共令牌。

第一段代码是您的活动库中的 clsCopyItem.cs 项。在此代码中,定义了工作流上下文的变量以及目标 Web 和目标库。我还使用了 CreateHistoryEvent 类在多个位置添加工作流历史记录中的条目,用于跟踪和故障排除。随意添加或删除,根据需要。

我也没有在此代码中放置广泛的错误处理或释放方法,因为我仍在尝试弄清楚。当我了解这一点时,或者如果有人真的乐于助人并提供一些建议,我将更新代码。

using System;
using System.ComponentModel;
using System.Workflow.ComponentModel.Compiler;
using System.Workflow.ComponentModel;
using System.Workflow.Activities;
using Microsoft.SharePoint;
using Microsoft.SharePoint.Workflow;
using Microsoft.SharePoint.WorkflowActions;

namespace ActivityLibrary
{
    public partial class clsCopyItem : SequenceActivity
    {
        public clsCopyItem()
        {
            InitializeComponent();
        }
        #region Dependency Properties
        public static DependencyProperty SiteUrlProperty = DependencyProperty.Register("SiteUrl",
            typeof(string), typeof(clsCopyItem), new PropertyMetadata(""));
        [DescriptionAttribute("Url of site where item is to be moved to")]
        [BrowsableAttribute(true)]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [ValidationOption(ValidationOption.Optional)]
        public string SiteUrl
        {
            get { return ((string)(base.GetValue(clsCopyItem.SiteUrlProperty))); }
            set { base.SetValue(clsCopyItem.SiteUrlProperty, value); }
        }

        public static DependencyProperty LibraryNameProperty = 
          DependencyProperty.Register("LibraryName", typeof(string), 
          typeof(clsCopyItem), new PropertyMetadata(""));
        [DescriptionAttribute("Name of library to move item to")]
        [BrowsableAttribute(true)]
        [DesignerSerializationVisibilityAttribute(DesignerSerializationVisibility.Visible)]
        [ValidationOption(ValidationOption.Optional)]
        public string LibraryName
        {
            get { return ((string)(base.GetValue(clsCopyItem.LibraryNameProperty))); }
            set { base.SetValue(clsCopyItem.LibraryNameProperty, value); }
        }
        public static DependencyProperty __ContextProperty = 
          System.Workflow.ComponentModel.DependencyProperty.Register(
          "__Context", typeof(WorkflowContext), typeof(clsCopyItem));
        [Description("Context")]
        [Category("Context")]
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public WorkflowContext __Context
        {
            get { return ((WorkflowContext)(base.GetValue(clsCopyItem.__ContextProperty))); }
            set { base.SetValue(clsCopyItem.__ContextProperty, value); }
        }
        public static DependencyProperty __ListIdProperty = 
          System.Workflow.ComponentModel.DependencyProperty.Register("__ListId", typeof(string), typeof(clsCopyItem));
        [Description("List Id")]
        [Category("List Id")]
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public string __ListId
        {
            get { return ((string)(base.GetValue(clsCopyItem.__ListIdProperty))); }
            set { base.SetValue(clsCopyItem.__ListIdProperty, value); }
        }
        public static DependencyProperty __ListItemProperty = 
          System.Workflow.ComponentModel.DependencyProperty.Register(
          "__ListItem", typeof(int), typeof(clsCopyItem));
        [Description("List Item")]
        [Category("List Item")]
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Visible)]
        public int __ListItem
        {
            get { return ((int)(base.GetValue(clsCopyItem.__ListItemProperty))); }
            set { base.SetValue(clsCopyItem.__ListItemProperty, value); }
        }

        #endregion

        public Guid workflowId = default(System.Guid);
        public SPWorkflowActivationProperties workflowProperties = new SPWorkflowActivationProperties();
        //private void codeCopyItem_ExecuteCode(object sender, EventArgs e)
        protected override ActivityExecutionStatus Execute(ActivityExecutionContext executionContext)
        {
            ISharePointService wfService = executionContext.GetService<ISharePointService>();
            SPListItem item = workflowProperties.Item;
            string targetSiteUrl = SiteUrl;
            string targetLib = LibraryName;
            string LogMessage = "Message logged to workflow history: ";

            //string targetSiteUrl = "http://testpublic.mwestling-lt/DocCenter";
            //string targetLib = "Documents";

            //Added to see if I can get the context items like file, etc.
            SPWeb contextWeb = __Context.Web;
            SPList contextList = contextWeb.Lists[new Guid(__ListId)];
            SPListItem contextItem = contextList.GetItemById(__ListItem);
            SPFile contextFile = contextItem.File;

            SPSecurity.RunWithElevatedPrivileges(delegate()
            {

                using (SPSite targetSite = new SPSite(targetSiteUrl))
                {
                    using (SPWeb targetWeb = targetSite.OpenWeb())
                    {
                        try
                        {
                            if (contextFile != null)
                            {
                                //Setup variables
                                SPFolder targetFolder = targetWeb.RootFolder.SubFolders[targetLib];
                                string strfutureFilePath = targetFolder + "/" + contextFile.Name;

                                //First test to see if the file exists on the target
                                SPFile isItThere = targetWeb.GetFile(strfutureFilePath);
                                if (isItThere.Exists)
                                {
                                    SPWorkflow.CreateHistoryEvent(targetWeb, __Context.WorkflowInstanceId, 0, 
                                      targetWeb.CurrentUser, TimeSpan.Zero, "Information", LogMessage + 
                                      "Target file exists, going to check it out if needed", string.Empty);
                                    //Check to see if it is already checked out, if so, undo the checkout
                                    if (isItThere.CheckOutType == SPFile.SPCheckOutType.None)
                                    {
                                        //If it exists, check it out
                                        isItThere.CheckOut();
                                    }
                                    else
                                    {
                                        isItThere.UndoCheckOut();
                                        isItThere.CheckOut();
                                    }
                                }
                                //Check out the source file                            
                                    SPWorkflow.CreateHistoryEvent(targetWeb, __Context.WorkflowInstanceId, 0, 
                                      targetWeb.CurrentUser, TimeSpan.Zero, "Information", 
                                      LogMessage + "Checking out source file", string.Empty);
                                if (contextFile.CheckOutType == SPFile.SPCheckOutType.None)
                                { contextFile.CheckOut(); }
                                else
                                { contextFile.UndoCheckOut(); contextFile.CheckOut(); }
                                //Try to overwrite, if not, then change code and add in the delete
                                    SPWorkflow.CreateHistoryEvent(targetWeb, __Context.WorkflowInstanceId, 0, targetWeb.CurrentUser, 
                                      TimeSpan.Zero, "Information", LogMessage + 
                                      "Copying file to destination", string.Empty);
                                SPFile movedFile = targetFolder.Files.Add(contextItem.File.Name, contextItem.File.OpenBinary(), true);
                                //Check in destination file
                                string movedFileComment = "Copied from " + contextFile.DocumentLibrary.Title + ".";
                                movedFile.CheckIn(movedFileComment);
                                //Check in source file and publish
                                string checkInComment = "File has been copied to the " + 
                                  targetFolder.Name + " library on the " + targetWeb.Title + " site";
                                contextFile.CheckIn(checkInComment);
                                contextFile.Publish(checkInComment);
                                contextFile.Approve(checkInComment);
                                    SPWorkflow.CreateHistoryEvent(targetWeb, __Context.WorkflowInstanceId, 0, 
                                      targetWeb.CurrentUser, TimeSpan.Zero, "Information", 
                                      LogMessage + "File copied and checked in", string.Empty);
                            }
                        }
                        catch (Exception ex)
                        {
                            string Message = ex.Message;
                            SPWorkflow.CreateHistoryEvent(targetWeb, __Context.WorkflowInstanceId, 0, 
                              targetWeb.CurrentUser, TimeSpan.Zero, "Error", 
                              "Message: " + Message, string.Empty);
                            throw ex;
                        }
                    }
                }
            });
            return ActivityExecutionStatus.Closed;
        }
    }
}
 

下一段代码将用于您的 CopyItemToAnotherLibrary.actions 文件中。它定义了工作流操作需要的参数,例如目标 URL 和目标库。请记住,注册程序集时,您需要使用您的令牌更新 PublicKeyToken。

<?xml version="1.0" encoding="utf-8" ?>
<WorkflowInfo>
  <Actions Sequential="then" Parallel="and">
    <Action Name="Move Item to Another Library"
      ClassName="ActivityLibrary.clsCopyItem"
      Assembly="ActivityLibrary, Version=1.0.0.0, Culture=neutral, PublicKeyToken=5cd1b18d3e72bd18"
      Category="Custom Actions"
      AppliesTo="all">
      <RuleDesigner Sentence="Send Item to Library %2 at Site URL %1">
        <FieldBind Field="SiteUrl" Text="Site URL" DesignerType="TextArea" Id="1"/>
        <FieldBind Field="LibraryName" Text="Library Name" DesignerType="TextArea" Id="2"/>
      </RuleDesigner>
      <Parameters>
        <Parameter Name="SiteUrl" Type="System.String, mscorlib" Direction="In" DesignerType="StringBuilder"
           Description="URL of the destination site. Must be in the form of http://ServerName/(SiteName)" />
        <Parameter Name="LibraryName" Type="System.String, mscorlib" Direction="In" DesignerType="StringBuilder"
           Description="Name of the destination library." />
        <Parameter Name="__Context" 
          Type="Microsoft.SharePoint.WorkflowActions.WorkflowContext, Microsoft.SharePoint.WorkflowActions" 
          Direction="In" DesignerType="Hide"/>
        <Parameter Name="__ListId" Type="System.String, mscorlib, mscorlib" Direction="In" DesignerType="Hide"/>
        <Parameter Name="__ListItem" Type="System.Int32, mscorlib, mscorlib" Direction="In" DesignerType="Hide"/>
      </Parameters>
    </Action>
  </Actions>
</WorkflowInfo> 

关注点

由于这是我第一次尝试编写自定义操作,我发现有很多关于编写自定义操作的好文章,以及用于将它们组合在一起的好代码片段。我确信有人会看到他们的代码片段,感谢您发布它。我包括了我在下面找到的一些有用的链接。

参考文献 

开发自定义工作流活动

创建自定义工作流站点活动

SharePoint 2010 自定义工作流活动

沙盒工作流活动

如何记录到历史记录列表

历史

初始发布 - 当提供建议等或我学到更多并创建更新时,将进行更新。

将文件从一个站点复制到另一个服务器或站点的工作流 - CodeProject - 代码之家
© . All rights reserved.