通过编程方式将整个文件夹复制并签入至SharePoint

自从本文作者为他的公司部署了SharePoint 2010后,其所在的IT部门就开始涌入很多如何使用SharePoint 2010的问题。公司里的人都明白SharePoint的原则,因此问题解释起来很容易。有一个问题很突出,之前他们都是使用文件服务器来存储文件,现在希望将那些内容迁移到SharePoint中,以便能够利用搜索功能。 所以,他们开始将文件复制到我们的SharePoint实例。 可是接下来他们突然意识到,要做到这一点,是一个巨大的任务,尤其是当面对一个包含5年的内容增长的文件储存库时。 如果是在SharePoint的用户界面中进行该操作,这个过程会很慢。所以,他们询问是否可以像在文件系统中一样进行快速的复制和粘贴?我的回答是肯定的,因为SharePoint文档库有一个内置的功能,可以打开Windows资源管理器视图。 从下图中你可以看到该功能的位置和说明信息:

[Sharepoint中的Windows资源管理器视图]

点击该图标,将打开Windows资源管理器,你可以像在文件系统中一样进行正常的文件拖放。 但紧接着他们又意识到另一个问题,上传上去的文件在SharePoint中搜索不到。我告诉他们过30分钟后再试试,新添加的内容不会实时显示在搜索中,因为内容需要先被SharePoint进行索引。

30分钟后...

他们仍然搜索不到。我曾看了一下,所有的文档都确实放在正确的位置上,但等一下,这些文档的图标有一个绿色的下箭头,这意味着该文档库打开了版本控制功能,所以默认情况下文档是签出状态的,而且从未被签入过。除非在文档的整个生命周期中至少被签入一次,否则它们是不会显示在搜索结果中的。 所以我告诉他们,需要手工选中那些文档,点击签入按钮,然后在弹出的签入对话框中点击确定。他们感到很满意。
注意 :如果没有打开文档库的版本控制,则不会出现签入签出的问题。

最近,当我在网上看堆栈溢出的相关资料时,看到了一篇有关通过编程方式复制文件到SharePoint的论坛回帖,突然意识到为什么当时我没有想过用这个办法呢。通过编程来完成签入,这也是本文将要实现的目标。

引用下列的命名控件。 你手头最好还要有SharePoint 2010的SDK

using System;
using Microsoft.SharePoint;
using System.IO;


首先,你需要一个递归函数把文件和目录从一个位置复制到另一个位置,而且由于在SharePoint中的文件可以通过文件系统进行定位,所以可以很容易地使用System.IO类来进行处理。 想要知道哪个目录是你想要的复制到的位置,有一个简单的办法。只需要查看一下上面提到的Windows资源管理器视图的地址即可,通常如果是这样的形式http://test.com/subfolder,那么我们复制的目标位置就应该为\\test.com\subfolder ,只需去掉http:并用反斜杠代替斜杠即可。

递归目录复制

public static void RecursiveCopy(string sSourceFolder, string sDestinationFolder)
{
    if (!Directory.Exists(sDestinationFolder))
    {
        Directory.CreateDirectory(sDestinationFolder);
    }
    string[] aFiles = Directory.GetFiles(sSourceFolder);
    foreach (string sFile in aFiles)
    {
        string sFileName = Path.GetFileName(sFile);
        string sDestination = Path.Combine(sDestinationFolder, sFileName);
        File.Copy(sFile, sDestination);
    }
    string[] aFolders = Directory.GetDirectories(sSourceFolder);
    foreach (string sFolder in aFolders)
    {
        string sFileNameSub = Path.GetFileName(sFolder);
        string sDestinationSub = Path.Combine(sDestinationFolder, sFileNameSub);
        RecursiveCopy(sFolder, sDestinationSub);
    }
}

该代码通过一个函数来递归的检查文件。 在你的环境里只需要替换SPSite构造函数参数中的地址为你实际的Team网站的http地址,并将SPDocumentLibrary后面的文档库名称改成你的文档库名称即可。

通过编程方式递归签出Sharepoint文件

public static void RecursiveMassCheckOut()
{
    using (SPSite oSharepointSite = new SPSite("http://sharepoint.com/MyTeamSite"))
    {
        using (SPWeb oSharepointWeb = oSharepointSite.OpenWeb())
        {
            SPDocumentLibrary oSharepointDocs = 
		(SPDocumentLibrary)oSharepointWeb.Lists["MyDocumentLibrary"];
            int iFolderCount = oSharepointDocs.Folders.Count;

            //签出根目录中的文件
            MassCheckOut(oSharepointDocs.RootFolder);    

            //签出子目录中的文件
            for (int i=0; i < iFolderCount; i++)
            {
                MassCheckOut(oSharepointDocs.Folders[i].Folder);
            }
        }
    }
}
public static void MassCheckOut(SPFolder oSharepointFolder)
{
    foreach (SPFile oSharepointFiles in oSharepointFolder.Files)
    {
        if (oSharepointFiles.CheckOutType == SPFile.SPCheckOutType.None)
        {
            oSharepointFiles.CheckOut();
        }
    }
}

作为一个有益的补充,所以在这里列出了递归签出文件的代码。

通过编程方式递归签入Sharepoint文件

回到正题。以下是完成签入的代码。

public static void RecursiveMassCheckIn()
{
    using (SPSite oSharepointSite = new SPSite("http://sharepoint.com/MyTeamSite"))
    {
        using (SPWeb oSharepointWeb = oSharepointSite.OpenWeb())
        {
            SPDocumentLibrary oSharepointDocs = 
		(SPDocumentLibrary)oSharepointWeb.Lists["MyDocumentLibrary"];
            int iFolderCount = oSharepointDocs.Folders.Count;

            //签入根目录中的文件
            MassCheckIn(oSharepointDocs.RootFolder);

            //签入子目录中的文件
            for (int i = 0; i < iFolderCount; i++)
            {
                MassCheckIn(oSharepointDocs.Folders[i].Folder);
            }
        }
    }
}
public static void MassCheckIn(SPFolder oSharepointFolder)
{
    foreach (SPFile oSharepointFiles in oSharepointFolder.Files)
    {
        if (oSharepointFiles.CheckOutType != SPFile.SPCheckOutType.None)
        {
            oSharepointFiles.CheckIn("该文件是通过编程方式签入的");
        }
    }
}

刚开始我使用的是.NET Framework 4,编译时,遇到如下的错误:

Unhandled Exception:System.PlatformNotSupportedException:Microsoft SharePoint is not supported with version 4.0.30319.1 of the Microsoft .Net Runtime.

at Microsoft
.SharePoint .Administration.SPConfigurationDatabase.get_Farm()

at Microsoft
.SharePoint.Administration.SPFarm.FindLocal(SPFarm& farm. Boolean & isJoined)

at Microsoft
.SharePoint.SPSite..ctor(String requestUrl)

at SharepointCopy
.MassCheckOut()

at SharePointCopy
.Process()

at Program
.Main(String[] args)

看起来是不支持.NET 4导致的,所以最好是在.NET Framework3.5下进行编译。 修改.NET框架版本后,编译一切正常。

现在,你可以完成像这样的命令行调用了:

RecursiveCopy(@"C:\LocalFolder\", @"\\sharepoint.com\MyTeamSite\MyDocumentLibrary\");
RecursiveMassCheckIn
();

 

参考资料

Programatically Copy and Check In a Full Directory to Sharepoint

posted @ 2010-10-13 23:32  Sunmoonfire  阅读(3410)  评论(6编辑  收藏  举报