Exporting lists for features programmatically using SolGen API and reflection
This post describes how I re-use SharePoint Solution Generator’s API by reverse engineering it using Reflector and invoking it via reflection. By leveraging the SPListTemplateExporter provided by SharePoint Solution Generator, we can export list definitions programmatically along with their companion files, and use them in features for automated build and packaging—eliminating tedious and error-prone manual XML authoring.
For my WCM Presence Factory (I’ll cover this in upcoming posts), I needed to export lists created with SharePoint Designer. This had to be done programmatically so that the factory could extract lists from existing sites for automated builds.
Once exported, I could use these list templates for packaging and support incremental updates in my WCM environment.
SharePoint Solution Generator (SolGen) already contains functionality for exporting lists, so I decided to reuse their API. Unfortunately, Microsoft marked all relevant types as internal, meaning I couldn’t directly reference or use them.
With some reflection, however, you can still instantiate internal types and invoke their methods to achieve the desired result.
Using Lutz Roeder’s Reflector, I inspected the API and identified the SPListTemplateExporter class as the key component for exporting list definitions.
Below is a condensed version of the implementation:
private static void ExportTemplate(string outputDir, string url, string listName)
{
using (SPSite site = new SPSite(url))
{
using (SPWeb web = site.OpenWeb())
{
// Access internal SPListTemplateExporter using reflection
Type t = Type.GetType(
"Microsoft.SharePoint.Tools.IO.SPListTemplateExporter, " +
"SPSolGen, Version=12.0.0.0"
);
// Create a new instance
object instance = Activator.CreateInstance(t);
// Create a list of GUIDs
Guid[] ids = new Guid[] { web.Lists[listName].ID };
// Set required properties
t.GetProperty("TargetSiteUrl")
.SetValue(instance, url, null);
t.GetProperty("ExportLocation")
.SetValue(instance, outputDir, null);
// Call Export(ICollection<Guid> ids)
t.GetMethod("Export", new Type[] { typeof(ICollection<Guid>) })
.Invoke(instance, new object[] { ids });
}
}
}
You can now generate a list definition along with companion files such as schema.xml, which can be directly used in feature packaging.
Example usage:
ExportTemplate(
@"C:\\",
"http://myserver/",
"MyList"
);
Notes
- Don’t forget to add a reference to the Solution Generator executable (
SPSolGen.exe). - The same reflection approach can be used to export other SharePoint artifacts.
- Lutz Roeder absolutely deserves a medal (or two) for Reflector.
Addendum
If your list schema contains lookup fields, they may not work out-of-the-box because they reference the target list by ID.
To fix this, modify the lookup definition in schema.xml:
ListName="Lists/<TargetListName>"
This allows SharePoint to resolve the relationship dynamically. Just ensure that the referenced list exists at deployment time.