问题
I have a problem with comportment of sharepoint.deployment.spimport.
I want to copy a web within the same site collection like that :
myserver/mysitecoll/website1
myserver/mysitecoll/website2
When I use the PowerShell command to execute this, it does it perfectly, the website2 is the same as the website1
Export-SPWeb -Identity http://myserver/mysitecoll/website1 -Path D:\mybackups\mytestsave\mybackup.bak
and
Import-SPWeb -Identity http://myserver/mysitecoll/website2 -Path D:\mybackups\mytestsave\mybackup.bak
But I need to do the same with c# I use
private void ExportSpWeb()
{
SPSite mySite = SPContext.Current.Site;
SPWeb myWeb = SPContext.Current.Web;
SPExportObject exportObject = new SPExportObject();
exportObject.Id = myWeb.ID;
exportObject.ParentId = mySite.ID;
exportObject.Type = SPDeploymentObjectType.Web;
SPExportSettings settings = new SPExportSettings();
settings.SiteUrl = mySite.Url;
settings.ExportMethod = SPExportMethodType.ExportAll;
settings.FileLocation = "D:\\mybackups\\mytestsave";
settings.BaseFileName = "test.cab";
settings.FileCompression = true;
settings.ExcludeDependencies = true;
settings.CommandLineVerbose = true;
settings.ExportObjects.Add(exportObject);
SPExport export = new SPExport(settings);
export.Run();
}
private void importSpWeb()
{
SPSite mySite = SPContext.Current.Site;
SPWeb myDestWeb = mySite.AllWebs["website2"];
SPImportSettings impsettings = new SPImportSettings();
impsettings.SiteUrl = mySite.Url;
impsettings.LogFilePath = "D:\\mybackups\\mytestsave\\test.log";
impsettings.WebUrl = myDestWeb.ServerRelativeUrl;
impsettings.FileLocation = "D:\\mybackups\\mytestsave";
impsettings.FileCompression = true;
impsettings.BaseFileName = "test.cab";
impsettings.RetainObjectIdentity = false;
SPImport import = new SPImport(impsettings);
import.Run();
}
But the comportment is not the same as PowerShell : Instead of being created using the specified WebUrl setting (http://myserver/mysitecoll/website2), the imported website is created as a new subsite with the path http://myserver/mysitecoll/website2/website1
How should I edit my code to obtain the same results as PowerShell?
回答1:
This question got me thinking very deeply, because I hit the wall as you did, but this led me to coming up with a quesion: Where is definition of sharepoint cmdlets and How to get their implementation?
So having the knowledge where Import-SPWeb
aka SPCmdletImportWeb
in Microsoft.SharePoint.PowerShell.dll
is I checked how it's done.
The tricky part is, that for some reason SPImportWeb
has some strange logic to modify WebUrl property and always add /
to the end. So in SPCmdletImportWeb
they are using SPImport
class Created
event to reset some properties.
For your case, when you're exporting and importing one SPWeb object you need add code below to your import object:
string webUrl = "website2";
// your stuff
SPImport import = new SPImport(impsettings);
import.Started += delegate(object sender, SPDeploymentEventArgs args)
{
SPImportObjectCollection rootObjects = args.RootObjects;
if (rootObjects[0].Type == SPDeploymentObjectType.Web)
{
rootObjects[0].TargetParentUrl = site.Url;
rootObjects[0].TargetName = webUrl;
return;
}
};
To look for the full code of SPCmdletImportWeb
get ILSpy and follow my mini tutorial in the first url.
Full test code:
[TestMethod]
public void Test_ExportSpWeb()
{
ExportSpWeb("http://lab/sites/custom-dev", "website1", @"C:\temp\bak\bak2.bak");
}
[TestMethod]
public void Test_ImportSpWeb()
{
ImportSpWeb("http://lab/sites/custom-dev", "website2", @"C:\temp\bak\bak2.bak");
}
private void ImportSpWeb(string siteUrl, string webUrl, string path)
{
using (SPSite site = new SPSite(siteUrl))
using (SPWeb web = site.OpenWeb(webUrl))
{
SPImportSettings impsettings = new SPImportSettings();
impsettings.SiteUrl = site.Url;
impsettings.LogFilePath = path + ".log";
impsettings.WebUrl = web.ServerRelativeUrl + "/" + webUrl;
impsettings.FileLocation = Path.GetDirectoryName(path);
impsettings.FileCompression = true;
impsettings.CommandLineVerbose = true;
impsettings.BaseFileName = Path.GetFileName(path);
impsettings.RetainObjectIdentity = false;
SPImport import = new SPImport(impsettings);
import.Started += delegate(object sender, SPDeploymentEventArgs args)
{
SPImportObjectCollection rootObjects = args.RootObjects;
if (rootObjects[0].Type == SPDeploymentObjectType.Web)
{
rootObjects[0].TargetParentUrl = site.Url;
rootObjects[0].TargetName = webUrl;
return;
}
};
import.Run();
}
}
private void ExportSpWeb(string siteUrl, string webUrl, string path)
{
using (SPSite site = new SPSite(siteUrl))
using (SPWeb web = site.OpenWeb(webUrl))
{
SPExportObject exportObject = new SPExportObject();
exportObject.Id = web.ID;
exportObject.ParentId = site.ID;
exportObject.Type = SPDeploymentObjectType.Web;
SPExportSettings settings = new SPExportSettings();
settings.SiteUrl = site.Url;
settings.ExportMethod = SPExportMethodType.ExportAll;
settings.FileLocation = Path.GetDirectoryName(path);
settings.BaseFileName = Path.GetFileName(path);
settings.LogFilePath = path + ".log";
settings.FileCompression = true;
settings.ExcludeDependencies = true;
settings.CommandLineVerbose = true;
settings.ExportObjects.Add(exportObject);
SPExport export = new SPExport(settings);
export.Run();
}
}
来源:https://stackoverflow.com/questions/44201669/how-to-import-an-spweb-using-c-sharp-to-have-the-same-behavior-than-powershell