SharePoint 2007 и 2010, содержат специальный Content Migration API, который умеет экспортировать данные из SharePoint, на файловую систему, и может инкрементально доставать изменения.
К сожалению этот API не позволяет вместо экспорта объектов на файловую систему, сделать с объектами что то свое. Покопавшись немного в Reflector я пришел к вот такой реализации энумерации объектов используя этот самый API.
static private string exportData(string srcRootUrl, string exportFileLocation, string exportChangeToken) { SPExportObject eobj = new SPExportObject(); eobj.Url = srcRootUrl; eobj.Type = SPDeploymentObjectType.Web; var expset = new SPExportSettings(); expset.ExportMethod = string.IsNullOrEmpty(exportChangeToken) ? SPExportMethodType.ExportAll : SPExportMethodType.ExportChanges; expset.SiteUrl = srcRootUrl; expset.FileLocation = exportFileLocation; expset.OverwriteExistingDataFile = true; expset.FileCompression = false; expset.AutoGenerateDataFileName = false; if (!string.IsNullOrEmpty(exportChangeToken)) expset.ExportChangeToken = exportChangeToken; expset.ExportObjects.Add(eobj); var export = new SPExport(expset); typeof(SPExport).InvokeMember("InitializeExport", BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, export, null); Console.WriteLine("Change token: {0}", export.Settings.CurrentChangeToken); var lastChangeToken = export.Settings.CurrentChangeToken; typeof(SPExport).InvokeMember("CalculateObjectsToExport", BindingFlags.Default | BindingFlags.InvokeMethod | BindingFlags.Instance | BindingFlags.NonPublic, null, export, null); PropertyInfo ObjectTotalProp = typeof(SPExport).GetProperty("ObjectsTotal", BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic); var total = (int)ObjectTotalProp.GetValue(export, null); Console.WriteLine("Total objects to migrate: {0}", total); PropertyInfo ObjectManagerProp = typeof(SPExport).GetProperty("ObjectManager", BindingFlags.Default | BindingFlags.Instance | BindingFlags.NonPublic); var ObjectManager = (IEnumerable)ObjectManagerProp.GetValue(export, null); var DeploymentObjectType = typeof(SPExport).Assembly.GetType("Microsoft.SharePoint.Deployment.ExportObject", true); var DeploymentObjectUrlProp = DeploymentObjectType.GetProperty("Url", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public); var DeploymentObjectTypeProp = DeploymentObjectType.GetProperty("Type", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public); var DeploymentObjectSPObjectProp = DeploymentObjectType.GetProperty("SPObject", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public); var DeploymentObjectObjectInfoProp = DeploymentObjectType.GetProperty("ObjectInfo", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public); var DeploymentObjectParentWebIdProp = DeploymentObjectType.GetProperty("ParentWebId", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public); var DeploymentObjectIdProp = DeploymentObjectType.GetProperty("Id", BindingFlags.Default | BindingFlags.Instance | BindingFlags.Public); foreach (object obj in ObjectManager) { var url = (string)DeploymentObjectUrlProp.GetValue(obj, null); var type = (Type)DeploymentObjectTypeProp.GetValue(obj, null); var spobj = DeploymentObjectSPObjectProp.GetValue(obj, null); var expobj = (SPExportObject)DeploymentObjectObjectInfoProp.GetValue(obj, null); var spObjId = (Guid)DeploymentObjectIdProp.GetValue(obj, null); var parentWebId = (Guid)DeploymentObjectParentWebIdProp.GetValue(obj, null); Console.WriteLine("--- object with type '{1}' from url='{0}' Id='{2}' parentWebId='{3}' spObject='{4}'", url, type, spObjId, parentWebId, spobj); // add your code here } return lastChangeToken; }
Использовать можно так - выдаст сначала все объекты, а потом будет отдавать изменения :
var srcRootUrl = @"http://server/MySite"; var exportFileLocation = @"C:\ExportFolder"; string lastChangeToken = ""; while (true) { Thread.Sleep(1000); Console.WriteLine("Export start with token '{0}'", lastChangeToken); lastChangeToken = exportData(srcRootUrl, exportFileLocation, lastChangeToken); }
Из артефактов осталась необходимость в фолдере на фаиловой системе куда сохраняется пустой файл "ExportSettings.xml"
Комментариев нет:
Отправка комментария