I've been doing quite a bit of SharePoint lately, and I feel there is still too much repetitive, manual effort involved in creating SharePoint solutions. One has to first create an empty class library project, and then add the folder structure and feature.xml, elements.xml, manifest.xml and wsp.ddf files. Next you have to keep track of file locations, both inside the solution and in the feature directory, and write post-build events to handle creation and dev deployment.
I have it in my mind to create a Visual Studio extensibility project to automate a lot of this stuff and provide visual designers to handle a lot of the grunt work. But that is a much larger task, so for now I am releasing my MakeCab task for MSBuild.
For those who are not familiar, the Microsoft Build Engine (MSBuild) is the underlying engine for building .NET solutions. It is available both as a command line utility, and as the hosted build tool for Visual Studio. MSBuild uses project files (.*proj) as input and they are xml based. The xml structure mainly contains Items, Properties, Targets and Tasks.
What I have written is a simple Task to execute MakeCab for a given .DDF file. The process is pretty simple: inherit from Microsoft.Build.Framework.Task and override the Execute method. Then I added a Required public property for the directive file input, and utilized that to create and run a System.Diagnostics.Process.
public
class
MakeCab : Task
{
private
string directivesFile;
public
override
bool Execute()
{
try
{
Log.LogMessage("Executing MakeCAB for " + directivesFile);
ProcessStartInfo si = new
ProcessStartInfo("makecab");
si.Arguments = "/f " + directivesFile;
Process.Start(si);
Log.LogMessage("Execution of MakeCAB succeeded for " + directivesFile);
return
true;
}
catch (Exception ex)
{
Log.LogMessage("Execution of MakeCAB failed for " + directivesFile +
". Reason: " + ex.Message);
Log.LogError(ex.Message);
return
false;
}
}
[Required]
public
string DirectivesFile
{
get
{
return directivesFile;
}
set
{
directivesFile = value;
}
}
}
I also signed my assembly and created a post-build event to register it in the GAC. The final step was to add the necessary nodes into the project xml file…
<UsingTask
TaskName="PlatinumBay.MSBuild.MakeCab.MakeCab"
AssemblyName="PlatinumBay.MSBuild.MakeCab, Version=1.0.0.0, Culture=neutral, PublicKeyToken=9805384e45235b26" />
<Target
Name="MyMakeCab">
<MakeCab
DirectivesFile="wsp.ddf" />
</Target>
…and add my new target to the DefaultTargets attribute:
<Project
DefaultTargets="Build;MakeCab"
xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
And that's it. Now when I build my project, my cabinet file gets created.
You can download the bits from the downloads section.
Download Source
Download Compiled