自从本文作者为他的公司部署了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